DEV Community

Vee Satayamas
Vee Satayamas

Posted on

1

A script for downloading PeerTube videos

Since peertube.social is closing down, I need a script for downloading all of my videos. I searched for this for a few minutes. I felt that it exists but I can't find, so I wrote mine in Common Lisp.

It probably works on other Common Lisp implementations too but I only tested on SBCL 2.0.1-5.fc34.

;; How to run
;; sbcl --load download-peertube-videos.lisp

(ql:quickload :jonathan)
(ql:quickload :dexador)
(ql:quickload :alexandria)
(ql:quickload :asdf)

(import 'alexandria:assoc-value)

(defparameter *username* "peertube-user-name")
(defparameter *hostname* "peertube.social")
(defparameter *get-videos-url* (format nil "https://~A/api/v1/accounts/~A/videos" *hostname* *username*))

(defparameter *videos-info* (assoc-value (jonathan:parse (dex:get *get-videos-url*)
                                                         :as :alist)
                                         "data"
                                         :test 'equal))

(defparameter *total* (assoc-value (jonathan:parse (dex:get (format nil "https://~A/api/v1/accounts/~A/videos" *hostname* *username*))
                                                   :as :alist)
                                   "total"
                                   :test 'equal))

(defparameter *count* 5)

(defun get-video-id (video-info)
  (assoc-value video-info "id" :test 'equal))

(defun get-video-json (video-id)
  (let ((video-info-url (format nil "https://~A/api/v1/videos/~A" *hostname* video-id)))
    (dex:get video-info-url)))

(defun download-video (video-details)
  (let* ((files (assoc-value video-details "files" :test 'equal))
         (download-url (assoc-value (car files) "fileDownloadUrl" :test 'equal))
         (cmd (format nil "wget ~A" download-url)))
    (format t "CMD: ~A~%" cmd)
    (uiop:run-program cmd :output t)))

(defun save-metadata (video-id video-json)
  (with-open-file (f (format nil "~A.json" video-id)
                     :direction :output
                     :if-exists :supersede
                     :if-does-not-exist :create)
    (write-string video-json f)))

(defun download-video-with-metadata (video-info)
  (let* ((video-id (get-video-id video-info))
         (video-json (get-video-json video-id))
         (video-details (jonathan:parse video-json
                                        :as :alist)))
    (save-metadata video-id video-json)
    (download-video video-details)))

(let ((i 0))
  (loop while (< i *total*)
        do
           (let* ((url (format nil "https://~A/api/v1/accounts/~A/videos?start=~A&count=~A" *hostname* *username* i *count*))

                  (videos-json (dex:get url))
                  (videos-alist (jonathan:parse videos-json :as :alist))
                  (videos-info (assoc-value videos-alist "data" :test 'equal)))
             (format t "*** i = ~A~%" i)
             (loop for video-info in videos-info
                   do
                      (download-video-with-metadata video-info)))
           (setq i (+ i *count*))))
Enter fullscreen mode Exit fullscreen mode

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs