executable_youtube-scm 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #!/usr/bin/env -S guile --no-auto-compile -e (youtube-scm) -s
  2. !#
  3. ;;;; youtube-scm --- SYNOPSIS
  4. ;;;; Copyright © 2020 Oleg Pykhalov <go.wigust@gmail.com>
  5. ;;;; Released under the GNU GPLv3 or any later version.
  6. (define-module (youtube-scm)
  7. #:use-module (srfi srfi-37)
  8. #:use-module (ice-9 match)
  9. #:use-module (ice-9 popen)
  10. #:use-module (ice-9 rdelim)
  11. #:use-module (ice-9 pretty-print)
  12. #:use-module (srfi srfi-1)
  13. #:export (main))
  14. ;;; Commentary:
  15. ;;;
  16. ;;; DESCRIPTION
  17. ;;;
  18. ;;; Code:
  19. (define %options
  20. (let ((display-and-exit-proc (lambda (msg)
  21. (lambda (opt name arg loads)
  22. (display msg) (quit)))))
  23. (list (option '(#\u "url") #t #f
  24. (lambda (opt name arg result)
  25. (alist-cons 'url arg result)))
  26. (option '(#\n "name") #t #f
  27. (lambda (opt name arg result)
  28. (alist-cons 'name arg result)))
  29. (option '(#\m "home-page") #t #f
  30. (lambda (opt name arg result)
  31. (alist-cons 'home-page arg result)))
  32. (option '(#\d "date") #t #f
  33. (lambda (opt name arg result)
  34. (alist-cons 'date arg result)))
  35. (option '(#\v "version") #f #f
  36. (display-and-exit-proc "youtube-scm version 0.0.1\n"))
  37. (option '(#\h "help") #f #f
  38. (display-and-exit-proc
  39. "Usage: youtube-scm ...")))))
  40. (define %default-options
  41. '())
  42. (define (system->string . args)
  43. (let* ((port (apply open-pipe* OPEN_READ args))
  44. (output (read-string port)))
  45. (close-pipe port)
  46. output))
  47. (define (hash file)
  48. (match (string-split (string-trim-right (system->string "guix" "download" file))
  49. #\newline)
  50. ((file hash) hash)))
  51. (define (main args)
  52. (define opts
  53. (args-fold (cdr (program-arguments))
  54. %options
  55. (lambda (opt name arg loads)
  56. (error "Unrecognized option `~A'" name))
  57. (lambda (op loads)
  58. (cons op loads))
  59. %default-options))
  60. (define url
  61. (assoc-ref opts 'url))
  62. (define date
  63. (or (assoc-ref opts 'date)
  64. (let* ((port (open-pipe (format #f "youtube-dl --ignore-errors --dump-single-json ~s | jq --raw-output .upload_date"
  65. url)
  66. OPEN_READ))
  67. (output (string-trim-right (read-string port))))
  68. (close-pipe port)
  69. output)))
  70. (define home-page
  71. (or (assoc-ref opts 'home-page)
  72. (let* ((port (open-pipe (format #f "youtube-dl --ignore-errors --dump-single-json ~s | jq --raw-output .channel_url"
  73. url)
  74. OPEN_READ))
  75. (output (string-trim-right (read-string port))))
  76. (close-pipe port)
  77. (if (string-prefix? "http://" output)
  78. (string-append "https://" (string-drop output (string-length "http://")))
  79. output))))
  80. (define name
  81. (or (assoc-ref opts 'name)
  82. (let* ((port (open-pipe (format #f "youtube-dl --ignore-errors --dump-single-json ~s | jq --raw-output .title"
  83. url)
  84. OPEN_READ))
  85. (output (string-trim-right (read-string port))))
  86. (close-pipe port)
  87. output)))
  88. (define %cache-directory
  89. (string-append "/tmp/" name "/"))
  90. (define %cache-file-video
  91. (string-append %cache-directory name "-" date ".mp4"))
  92. (define %cache-file-audio
  93. (string-append %cache-directory name "-" date ".m4a"))
  94. (system* "youtube-dl" "--no-check-certificate" "--no-cache-dir" "--format" "140" "--output" %cache-file-audio url)
  95. (system* "youtube-dl" "--no-check-certificate" "--no-cache-dir" "--format" "137" "--output" %cache-file-video url)
  96. (pretty-print `(define-public ,(string->symbol (string-append "video-" name))
  97. (package (name ,(string-append "video-" name))
  98. (version ,date)
  99. (source (origin (method youtube-dl-fetch)
  100. (uri (youtube-dl-reference
  101. (url ,url)
  102. (format 137)))
  103. (file-name (string-append (string-drop name (string-length "video-")) "-" version ".mp4"))
  104. (sha256
  105. (base32 ,(hash %cache-file-video)))))
  106. (build-system ffmpeg-build-system)
  107. (inputs
  108. `(("audio" ,(origin
  109. (method youtube-dl-fetch)
  110. (uri (youtube-dl-reference
  111. (url ,url)
  112. (format 140)))
  113. (file-name (string-append (string-drop name (string-length "video-")) "-" version ".m4a"))
  114. (sha256
  115. (base32 ,(hash %cache-file-audio)))))))
  116. (home-page ,home-page)
  117. (synopsis "")
  118. (description "")
  119. (license #f)))
  120. #:max-expr-width 79))
  121. ;;; youtube-scm ends here