123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- #!/usr/bin/env -S guile --no-auto-compile -e main -s
- !#
- ;;; convert-music --- Convert video clips to audio only
- ;;; Copyright © 2019, 2022 Oleg Pykhalov <go.wigust@gmail.com>
- ;;;
- ;;; This file is part of convert-music.
- ;;;
- ;;; convert-music is free software; you can redistribute it and/or modify it
- ;;; under the terms of the GNU General Public License as published by
- ;;; the Free Software Foundation; either version 3 of the License, or (at
- ;;; your option) any later version.
- ;;;
- ;;; convert-music is distributed in the hope that it will be useful, but
- ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;; GNU General Public License for more details.
- ;;;
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with convert-music. If not, see <http://www.gnu.org/licenses/>.
- ;; Convert video clips in /srv/music directory to audio files without a video
- ;; part and store them in /srv/audio directory. To do that, run:
- ;;
- ;; peertube /srv/music
- (use-modules (ice-9 format)
- (ice-9 ftw)
- (ice-9 match)
- (ice-9 popen)
- (ice-9 rdelim)
- (ice-9 readline)
- (json)
- (srfi srfi-1)
- (srfi srfi-26)
- (srfi srfi-34)
- (srfi srfi-37)
- (guix build utils))
- (define (list-files dir)
- (filter (match-lambda
- ((name #(_ _ _ _ _ _ _ _ _ _ _ _ _ 'regular _ _ _ _)) name)
- (_ #f))
- (file-system-tree dir)))
- (define %options
- (let ((display-and-exit-proc (lambda (msg)
- (lambda (opt name arg loads)
- (display msg) (quit)))))
- (list (option '(#\v "version") #f #f
- (display-and-exit-proc "convert-music version 0.0.1\n"))
- (option '(#\h "help") #f #f
- (display-and-exit-proc
- "Usage: convert-music /srv/music /srv/audio ...")))))
- (define %default-options
- '())
- (define %peertube-api-url
- (and=> (getenv "PEERTUBE_API_URL")
- (lambda (peertube-api-url)
- peertube-api-url)))
- (define %peertube-username
- (and=> (getenv "PEERTUBE_USERNAME")
- (lambda (peertube-username)
- peertube-username)))
- (define %peertube-password
- (and=> (getenv "PEERTUBE_PASSWORD")
- (lambda (peertube-password)
- peertube-password)))
- (define %peertube-channel-id
- (and=> (getenv "PEERTUBE_CHANNEL_ID")
- (lambda (peertube-channel-id)
- peertube-channel-id)))
- (define %peertube-category
- (and=> (getenv "PEERTUBE_CATEGORY")
- (lambda (peertube-category)
- peertube-category)))
- (define %peertube-playlist-id
- (and=> (getenv "PEERTUBE_PLAYLIST_ID")
- (lambda (peertube-playlist-id)
- peertube-playlist-id)))
- (define %peertube-privacy
- (and=> (getenv "PEERTUBE_PRIVACY")
- (lambda (peertube-privacy)
- peertube-privacy)))
- (define (peertube-client-id)
- (let* ((port (open-pipe* OPEN_READ "curl"
- (string-append
- %peertube-api-url "/oauth-clients/local")
- "--silent"))
- (output (read-string port)))
- (close-port port)
- (string-trim-right output #\newline)))
- (define (peertube-access-token client-id client-secret)
- (let* ((port (open-pipe* OPEN_READ "curl"
- (string-append %peertube-api-url "/users/token")
- "--silent"
- "--data" (format #f "client_id=~a" client-id)
- "--data" (format #f "client_secret=~a" client-secret)
- "--data" "grant_type=password"
- "--data" "response_type=code"
- "--data" (format #f "username=~a" %peertube-username)
- "--data" (format #f "password=~a" %peertube-password)))
- (output (read-string port)))
- (close-port port)
- (string-trim-right output #\newline)))
- (define (append-to-file name body)
- (let ((file (open-file name "a")))
- (display body file)
- (close-port file)))
- (define (main . args)
- (define opts
- (args-fold (cdr (program-arguments))
- %options
- (lambda (opt name arg loads)
- (error "Unrecognized option `~A'" name))
- (lambda (op loads)
- (cons op loads))
- %default-options))
- (define input-directory
- (first (reverse opts)))
- (define client-id+secret
- (json-string->scm (peertube-client-id)))
- (define client-id
- (assoc-ref client-id+secret "client_id"))
- (define client-secret
- (assoc-ref client-id+secret "client_secret"))
- (define access-token
- (assoc-ref
- (json-string->scm
- (peertube-access-token client-id client-secret))
- "access_token"))
- (for-each (lambda (file)
- (match file
- ((n ... ext)
- (let* ((input (string-append input-directory "/"
- (string-join file ".")))
- (output-file-name
- (match (string-split (basename input) #\.)
- ((file-name ... file-extension)
- (string-join file-name "."))
- ((file-name file-extension)
- file-name)))
- (video-upload-output (string-append output-file-name ".json")))
- (if (any (lambda (file)
- (string= file input))
- (string-split
- (with-input-from-file "peertube.log"
- read-string)
- #\newline))
- (format #t "~%Skip already uploaded ~a file.~%" input)
- (begin
- (format #t "input: ~a~%" input)
- (format #t "output: ~a~%" output-file-name)
- (guard (c ((invoke-error? c)
- (report-invoke-error c)
- (append-to-file "peertube-error.log" (string-append "\n" input))
- #f))
- (invoke
- "curl" (string-append %peertube-api-url "/videos/upload")
- "--fail"
- "--max-time" "6000"
- "--header" (format #f "Authorization: Bearer ~a" access-token)
- "--form" (format #f "videofile=@~a" input)
- "--form" (format #f "name=~a" output-file-name)
- "--form" (format #f "channelId=~a" %peertube-channel-id)
- "--form" (format #f "privacy=~a" %peertube-privacy)
- "--form" (format #f "category=~a" %peertube-category)
- "--form" "waitTranscoding=1"
- "--output" video-upload-output))
- (display "\nSleep for 30 to wait for API.\n")
- (sleep 30)
- (let ((uuid (assoc-ref (assoc-ref (json-string->scm
- (with-input-from-file video-upload-output
- read-string))
- "video")
- "uuid")))
-
- (guard (c ((invoke-error? c)
- (report-invoke-error c)
- (append-to-file "peertube-playlist-error.log" (string-append "\n" input))
- #f))
- (invoke "curl"
- (string-append %peertube-api-url "/video-playlists/" %peertube-playlist-id "/videos")
- "--fail"
- "--header" (format #f "Authorization: Bearer ~a" access-token)
- "--data" (format #f "videoId=~a" uuid))))
- (let loop ()
- (if (= (system* "pgrep" "--full" "--list-full" "ffmpeg")
- 256)
- #t
- (begin
- (display "Wait until ffmpeg processes do not exist.\n")
- (sleep 30)
- (loop))))
- (newline)
- (append-to-file "peertube.log" (string-append "\n" input))))))))
- (map (cut string-split <> #\.)
- (map (match-lambda ((file _ ...) file))
- (list-files input-directory)))))
|