aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/tubo/api.clj263
-rw-r--r--src/backend/tubo/api/channels.clj29
-rw-r--r--src/backend/tubo/api/comments.clj45
-rw-r--r--src/backend/tubo/api/items.clj49
-rw-r--r--src/backend/tubo/api/playlists.clj31
-rw-r--r--src/backend/tubo/api/services.clj82
-rw-r--r--src/backend/tubo/api/streams.clj36
7 files changed, 263 insertions, 272 deletions
diff --git a/src/backend/tubo/api.clj b/src/backend/tubo/api.clj
new file mode 100644
index 0000000..f5e1a2e
--- /dev/null
+++ b/src/backend/tubo/api.clj
@@ -0,0 +1,263 @@
+(ns tubo.api
+ (:require
+ [clojure.java.data :as j]
+ [ring.util.codec :refer [url-decode]])
+ (:import
+ org.schabi.newpipe.extractor.channel.ChannelInfo
+ org.schabi.newpipe.extractor.comments.CommentsInfo
+ org.schabi.newpipe.extractor.kiosk.KioskInfo
+ org.schabi.newpipe.extractor.playlist.PlaylistInfo
+ org.schabi.newpipe.extractor.search.SearchInfo
+ org.schabi.newpipe.extractor.stream.StreamInfo
+ org.schabi.newpipe.extractor.NewPipe
+ org.schabi.newpipe.extractor.Page))
+
+(defn get-stream-item
+ [stream]
+ {:type :stream
+ :service-id (.getServiceId stream)
+ :url (.getUrl stream)
+ :name (.getName stream)
+ :thumbnail-url (.getThumbnailUrl stream)
+ :uploader-name (.getUploaderName stream)
+ :uploader-url (.getUploaderUrl stream)
+ :uploader-avatar (.getUploaderAvatarUrl stream)
+ :upload-date (.getTextualUploadDate stream)
+ :short-description (.getShortDescription stream)
+ :duration (.getDuration stream)
+ :view-count (when-not (= (.getViewCount stream) -1) (.getViewCount stream))
+ :uploaded
+ (when (.getUploadDate stream)
+ (.. stream (getUploadDate) (offsetDateTime) (toInstant) (toEpochMilli)))
+ :verified? (.isUploaderVerified stream)})
+
+(defn get-channel-item
+ [channel]
+ {:type :channel
+ :service-id (.getServiceId channel)
+ :url (.getUrl channel)
+ :name (.getName channel)
+ :thumbnail-url (.getThumbnailUrl channel)
+ :description (.getDescription channel)
+ :subscriber-count (when-not (= (.getSubscriberCount channel) -1)
+ (.getSubscriberCount channel))
+ :stream-count (when-not (= (.getStreamCount channel) -1)
+ (.getStreamCount channel))
+ :verified? (.isVerified channel)})
+
+(defn get-playlist-item
+ [playlist]
+ {:type :playlist
+ :service-id (.getServiceId playlist)
+ :url (.getUrl playlist)
+ :name (.getName playlist)
+ :thumbnail-url (.getThumbnailUrl playlist)
+ :uploader-name (.getUploaderName playlist)
+ :stream-count (when-not (= (.getStreamCount playlist) -1)
+ (.getStreamCount playlist))})
+
+(defn get-items
+ [items]
+ (map #(case (.name (.getInfoType %))
+ "STREAM" (get-stream-item %)
+ "CHANNEL" (get-channel-item %)
+ "PLAYLIST" (get-playlist-item %))
+ items))
+
+(defn get-common-info
+ [info]
+ {:name (.getName info)
+ :service-id (.getServiceId info)
+ :related-streams (get-items (.getRelatedItems info))})
+
+(defn get-channel
+ ([url]
+ (let [info (ChannelInfo/getInfo (url-decode url))]
+ (merge (get-common-info info)
+ {:id (.getId info)
+ :verified? (.isVerified info)
+ :banner (.getBannerUrl info)
+ :description (.getDescription info)
+ :avatar (.getAvatarUrl info)
+ :subscriber-count (when-not (= (.getSubscriberCount info) -1)
+ (.getSubscriberCount info))
+ :donation-links (.getDonationLinks info)
+ :next-page (j/from-java (.getNextPage info))})))
+ ([url page-url]
+ (let [service (NewPipe/getServiceByUrl (url-decode url))
+ info (ChannelInfo/getMoreItems service
+ (url-decode url)
+ (Page. (url-decode page-url)))]
+ {:related-streams (get-items (.getItems info))
+ :next-page (j/from-java (.getNextPage info))})))
+
+(defn get-stream
+ [url]
+ (let [info (StreamInfo/getInfo (url-decode url))]
+ (merge (get-common-info info)
+ {:url (.getUrl info)
+ :thumbnail-url (.getThumbnailUrl info)
+ :description (.. info (getDescription) (getContent))
+ :duration (.getDuration info)
+ :upload-date (.getTextualUploadDate info)
+ :uploader-name (.getUploaderName info)
+ :uploader-url (.getUploaderUrl info)
+ :uploader-avatar (.getUploaderAvatarUrl info)
+ :uploader-verified? (.isUploaderVerified info)
+ :tags (.getTags info)
+ :category (.getCategory info)
+ :view-count (when-not (= (.getViewCount info) -1)
+ (.getViewCount info))
+ :like-count (when-not (= (.getLikeCount info) -1)
+ (.getLikeCount info))
+ :dislike-count (when-not (= (.getDislikeCount info) -1)
+ (.getDislikeCount info))
+ :subscriber-count (when-not (= (.getUploaderSubscriberCount info)
+ -1)
+ (.getUploaderSubscriberCount info))
+ :audio-streams (j/from-java (.getAudioStreams info))
+ :video-streams (j/from-java (.getVideoStreams info))
+ :hls-url (.getHlsUrl info)
+ :dash-mpd-url (.getDashMpdUrl info)})))
+
+(defn get-playlist
+ ([url]
+ (let [service (NewPipe/getServiceByUrl (url-decode url))
+ info (PlaylistInfo/getInfo service (url-decode url))]
+ (merge (get-common-info info)
+ {:id (.getId info)
+ :playlist-type (j/from-java (.getPlaylistType info))
+ :thumbnail-url (.getThumbnailUrl info)
+ :banner-url (.getBannerUrl info)
+ :uploader-name (.getUploaderName info)
+ :uploader-url (.getUploaderUrl info)
+ :uploader-avatar (.getUploaderAvatarUrl info)
+ :stream-count (.getStreamCount info)
+ :next-page (j/from-java (.getNextPage info))})))
+ ([url page-url]
+ (let [service (NewPipe/getServiceByUrl (url-decode url))
+ info
+ (PlaylistInfo/getMoreItems service url (Page. (url-decode page-url)))]
+ {:next-page (j/from-java (.getNextPage info))
+ :related-streams (get-items (.getItems info))})))
+
+(defn get-comment-item
+ [item extractor info]
+ {:id (.getCommentId item)
+ :text (.. item (getCommentText) (getContent))
+ :upload-date (.getTextualUploadDate item)
+ :uploader-name (.getUploaderName item)
+ :uploader-url (.getUploaderUrl item)
+ :uploader-avatar (.getUploaderAvatarUrl item)
+ :uploader-verified? (.isUploaderVerified item)
+ :like-count (when-not (= (.getLikeCount item) -1)
+ (.getLikeCount item))
+ :reply-count (when-not (= (.getReplyCount item) -1)
+ (.getReplyCount item))
+ :hearted-by-uploader? (.isHeartedByUploader item)
+ :pinned? (.isPinned item)
+ :stream-position (when-not (= (.getStreamPosition item) -1)
+ (.getStreamPosition item))
+ :replies (when (.getReplies item)
+ (if extractor
+ (let [comments-page (.getPage extractor
+ (.getReplies item))]
+ {:next-page (when (.hasNextPage comments-page)
+ (j/from-java (.getNextPage
+ comments-page)))
+ :items (map #(get-comment-item %
+ extractor
+ info)
+ (.getItems comments-page))})
+ (j/from-java (.getReplies item))))})
+
+(defn get-comments
+ ([url]
+ (let [info (CommentsInfo/getInfo (url-decode url))
+ extractor (.getCommentsExtractor info)]
+ {:comments (map #(get-comment-item % extractor info)
+ (.getRelatedItems info))
+ :next-page (j/from-java (.getNextPage info))
+ :disabled? (.isCommentsDisabled info)}))
+ ([url page-url]
+ (let [service (NewPipe/getServiceByUrl (url-decode url))
+ info (CommentsInfo/getMoreItems service
+ (url-decode url)
+ (Page. (url-decode page-url)))]
+ {:comments (map #(get-comment-item % nil info) (.getItems info))
+ :next-page (j/from-java (.getNextPage info))
+ :disabled? false})))
+
+(defn get-search
+ ([service-id query content-filters sort-filter]
+ (let [service (NewPipe/getService service-id)
+ query-handler
+ (.. service
+ (getSearchQHFactory)
+ (fromQuery query (or content-filters '()) (or sort-filter "")))
+ info (SearchInfo/getInfo service query-handler)]
+ {:items (get-items (.getRelatedItems info))
+ :next-page (j/from-java (.getNextPage info))
+ :service-id service-id
+ :search-suggestion (.getSearchSuggestion info)
+ :corrected-search? (.isCorrectedSearch info)}))
+ ([service-id query content-filters sort-filter page-url]
+ (let [service (NewPipe/getService service-id)
+ url (url-decode page-url)
+ query-handler
+ (.. service
+ (getSearchQHFactory)
+ (fromQuery query (or content-filters '()) (or sort-filter "")))
+ info (SearchInfo/getMoreItems service query-handler (Page. url))]
+ {:items (get-items (.getItems info))
+ :next-page (j/from-java (.getNextPage info))})))
+
+(defn get-kiosk
+ ([service-id]
+ (let [service (NewPipe/getService service-id)
+ extractor (doto (.getDefaultKioskExtractor (.getKioskList service))
+ (.fetchPage))
+ info (KioskInfo/getInfo extractor)]
+ {:id (.getId info)
+ :url (.getUrl info)
+ :service-id service-id
+ :next-page (j/from-java (.getNextPage info))
+ :related-streams (get-items (.getRelatedItems info))}))
+ ([kiosk-id service-id]
+ (let [service (NewPipe/getService service-id)
+ extractor
+ (doto (.getExtractorById (.getKioskList service) kiosk-id nil)
+ (.fetchPage))
+ info (KioskInfo/getInfo extractor)]
+ {:id (.getId info)
+ :url (.getUrl info)
+ :service-id service-id
+ :next-page (j/from-java (.getNextPage info))
+ :related-streams (get-items (.getRelatedItems info))}))
+ ([kiosk-id service-id page-url]
+ (let [service (NewPipe/getService service-id)
+ extractor (.getExtractorById (.getKioskList service) kiosk-id nil)
+ url (url-decode page-url)
+ kiosk-info (KioskInfo/getInfo extractor)
+ info (KioskInfo/getMoreItems service
+ (.getUrl kiosk-info)
+ (Page. url))]
+ {:next-page (j/from-java (.getNextPage info))
+ :related-streams (get-items (.getItems info))})))
+
+(defn get-kiosks
+ [service-id]
+ (let [service (NewPipe/getService service-id)
+ kiosks (.getKioskList service)]
+ {:default-kiosk (.getDefaultKioskId kiosks)
+ :available-kiosks (.getAvailableKiosks kiosks)}))
+
+(defn get-service
+ [service]
+ {:id (.getServiceId service)
+ :info (j/from-java (.getServiceInfo service))
+ :base-url (.getBaseUrl service)})
+
+(defn get-services
+ []
+ (map get-service (NewPipe/getServices)))
diff --git a/src/backend/tubo/api/channels.clj b/src/backend/tubo/api/channels.clj
deleted file mode 100644
index f19a65e..0000000
--- a/src/backend/tubo/api/channels.clj
+++ /dev/null
@@ -1,29 +0,0 @@
-(ns tubo.api.channels
- (:require
- [clojure.java.data :as j]
- [ring.util.codec :refer [url-decode]]
- [tubo.api.items :as items])
- (:import
- org.schabi.newpipe.extractor.channel.ChannelInfo
- org.schabi.newpipe.extractor.NewPipe
- org.schabi.newpipe.extractor.Page))
-
-(defn get-channel
- ([url]
- (let [info (ChannelInfo/getInfo (url-decode url))]
- {:id (.getId info)
- :name (.getName info)
- :verified? (.isVerified info)
- :banner (.getBannerUrl info)
- :avatar (.getAvatarUrl info)
- :description (.getDescription info)
- :subscriber-count (when-not (= (.getSubscriberCount info) -1) (.getSubscriberCount info))
- :donation-links (.getDonationLinks info)
- :next-page (j/from-java (.getNextPage info))
- :related-streams (items/get-items (.getRelatedItems info))
- :service-id (.getServiceId info)}))
- ([url page-url]
- (let [service (NewPipe/getServiceByUrl (url-decode url))
- info (ChannelInfo/getMoreItems service (url-decode url) (Page. (url-decode page-url)))]
- {:related-streams (items/get-items (.getItems info))
- :next-page (j/from-java (.getNextPage info))})))
diff --git a/src/backend/tubo/api/comments.clj b/src/backend/tubo/api/comments.clj
deleted file mode 100644
index 7790a1a..0000000
--- a/src/backend/tubo/api/comments.clj
+++ /dev/null
@@ -1,45 +0,0 @@
-(ns tubo.api.comments
- (:require
- [clojure.java.data :as j]
- [ring.util.codec :refer [url-decode]])
- (:import
- org.schabi.newpipe.extractor.NewPipe
- org.schabi.newpipe.extractor.Page
- org.schabi.newpipe.extractor.ListExtractor
- org.schabi.newpipe.extractor.comments.CommentsInfoItem
- org.schabi.newpipe.extractor.comments.CommentsInfo))
-
-(defn get-comment-item
- [item extractor]
- {:id (.getCommentId item)
- :text (.. item (getCommentText) (getContent))
- :uploader-name (.getUploaderName item)
- :uploader-avatar (.getUploaderAvatarUrl item)
- :uploader-url (.getUploaderUrl item)
- :uploader-verified? (.isUploaderVerified item)
- :upload-date (.getTextualUploadDate item)
- :like-count (when-not (= (.getLikeCount item) -1) (.getLikeCount item))
- :reply-count (when-not (= (.getReplyCount item) -1) (.getReplyCount item))
- :hearted-by-uploader? (.isHeartedByUploader item)
- :pinned? (.isPinned item)
- :stream-position (when-not (= (.getStreamPosition item) -1) (.getStreamPosition item))
- :replies (when (.getReplies item)
- (if extractor
- (let [comments-page (.getPage extractor (.getReplies item))]
- {:next-page (when (.hasNextPage comments-page) (j/from-java (.getNextPage comments-page)))
- :items (map #(get-comment-item % extractor) (.getItems comments-page))})
- (j/from-java (.getReplies item))))})
-
-(defn get-comments
- ([url]
- (let [info (CommentsInfo/getInfo (url-decode url))
- extractor (.getCommentsExtractor info)]
- {:comments (map #(get-comment-item % extractor) (.getRelatedItems info))
- :next-page (j/from-java (.getNextPage info))
- :disabled? (.isCommentsDisabled info)}))
- ([url page-url]
- (let [service (NewPipe/getServiceByUrl (url-decode url))
- info (CommentsInfo/getMoreItems service (url-decode url) (Page. (url-decode page-url)))]
- {:comments (map #(get-comment-item % nil) (.getItems info))
- :next-page (j/from-java (.getNextPage info))
- :disabled? false})))
diff --git a/src/backend/tubo/api/items.clj b/src/backend/tubo/api/items.clj
deleted file mode 100644
index 8519449..0000000
--- a/src/backend/tubo/api/items.clj
+++ /dev/null
@@ -1,49 +0,0 @@
-(ns tubo.api.items)
-
-(defn get-stream-item
- [stream]
- {:type :stream
- :service-id (.getServiceId stream)
- :url (.getUrl stream)
- :name (.getName stream)
- :thumbnail-url (.getThumbnailUrl stream)
- :uploader-name (.getUploaderName stream)
- :uploader-url (.getUploaderUrl stream)
- :uploader-avatar (.getUploaderAvatarUrl stream)
- :upload-date (.getTextualUploadDate stream)
- :short-description (.getShortDescription stream)
- :duration (.getDuration stream)
- :view-count (when-not (= (.getViewCount stream) -1) (.getViewCount stream))
- :uploaded (when (.getUploadDate stream)
- (.. stream (getUploadDate) (offsetDateTime) (toInstant) (toEpochMilli)))
- :verified? (.isUploaderVerified stream)})
-
-(defn get-channel-item
- [channel]
- {:type :channel
- :service-id (.getServiceId channel)
- :url (.getUrl channel)
- :name (.getName channel)
- :thumbnail-url (.getThumbnailUrl channel)
- :description (.getDescription channel)
- :subscriber-count (when-not (= (.getSubscriberCount channel) -1) (.getSubscriberCount channel))
- :stream-count (when-not (= (.getStreamCount channel) -1) (.getStreamCount channel))
- :verified? (.isVerified channel)})
-
-(defn get-playlist-item
- [playlist]
- {:type :playlist
- :service-id (.getServiceId playlist)
- :url (.getUrl playlist)
- :name (.getName playlist)
- :thumbnail-url (.getThumbnailUrl playlist)
- :uploader-name (.getUploaderName playlist)
- :stream-count (when-not (= (.getStreamCount playlist) -1) (.getStreamCount playlist))})
-
-(defn get-items
- [items]
- (map #(case (.name (.getInfoType %))
- "STREAM" (get-stream-item %)
- "CHANNEL" (get-channel-item %)
- "PLAYLIST" (get-playlist-item %))
- items))
diff --git a/src/backend/tubo/api/playlists.clj b/src/backend/tubo/api/playlists.clj
deleted file mode 100644
index 9ded200..0000000
--- a/src/backend/tubo/api/playlists.clj
+++ /dev/null
@@ -1,31 +0,0 @@
-(ns tubo.api.playlists
- (:require
- [clojure.java.data :as j]
- [ring.util.codec :refer [url-decode]]
- [tubo.api.items :as items])
- (:import
- org.schabi.newpipe.extractor.playlist.PlaylistInfo
- org.schabi.newpipe.extractor.Page
- org.schabi.newpipe.extractor.NewPipe))
-
-(defn get-playlist
- ([url]
- (let [service (NewPipe/getServiceByUrl (url-decode url))
- info (PlaylistInfo/getInfo service (url-decode url))]
- {:id (.getId info)
- :name (.getName info)
- :playlist-type (j/from-java (.getPlaylistType info))
- :thumbnail-url (.getThumbnailUrl info)
- :banner-url (.getBannerUrl info)
- :uploader-name (.getUploaderName info)
- :uploader-url (.getUploaderUrl info)
- :uploader-avatar (.getUploaderAvatarUrl info)
- :stream-count (.getStreamCount info)
- :next-page (j/from-java (.getNextPage info))
- :related-streams (items/get-items (.getRelatedItems info))
- :service-id (.getServiceId info)}))
- ([url page-url]
- (let [service (NewPipe/getServiceByUrl (url-decode url))
- info (PlaylistInfo/getMoreItems service url (Page. (url-decode page-url)))]
- {:next-page (j/from-java (.getNextPage info))
- :related-streams (items/get-items (.getItems info))})))
diff --git a/src/backend/tubo/api/services.clj b/src/backend/tubo/api/services.clj
deleted file mode 100644
index ab1a655..0000000
--- a/src/backend/tubo/api/services.clj
+++ /dev/null
@@ -1,82 +0,0 @@
-(ns tubo.api.services
- (:require
- [clojure.java.data :as j]
- [ring.util.codec :refer [url-encode url-decode]]
- [tubo.api.items :as items])
- (:import
- org.schabi.newpipe.extractor.kiosk.KioskInfo
- org.schabi.newpipe.extractor.kiosk.KioskList
- org.schabi.newpipe.extractor.InfoItem
- org.schabi.newpipe.extractor.NewPipe
- org.schabi.newpipe.extractor.Page
- org.schabi.newpipe.extractor.StreamingService
- org.schabi.newpipe.extractor.search.SearchInfo))
-
-(defn search
- ([service-id query content-filters sort-filter]
- (let [service (NewPipe/getService service-id)
- query-handler (.. service
- (getSearchQHFactory)
- (fromQuery query (or content-filters '()) (or sort-filter "")))
- info (SearchInfo/getInfo service query-handler)]
- {:items (items/get-items (.getRelatedItems info))
- :next-page (j/from-java (.getNextPage info))
- :service-id service-id
- :search-suggestion (.getSearchSuggestion info)
- :corrected-search? (.isCorrectedSearch info)}))
- ([service-id query content-filters sort-filter page-url]
- (let [service (NewPipe/getService service-id)
- url (url-decode page-url)
- query-handler (.. service
- (getSearchQHFactory)
- (fromQuery query (or content-filters '()) (or sort-filter "")))
- info (SearchInfo/getMoreItems service query-handler (Page. url))]
- {:items (items/get-items (.getItems info))
- :next-page (j/from-java (.getNextPage info))})))
-
-(defn get-kiosk
- ([service-id]
- (let [service (NewPipe/getService service-id)
- extractor (doto (.getDefaultKioskExtractor (.getKioskList service))
- (.fetchPage))
- info (KioskInfo/getInfo extractor)]
- {:id (.getId info)
- :url (.getUrl info)
- :service-id service-id
- :next-page (j/from-java (.getNextPage info))
- :related-streams (items/get-items (.getRelatedItems info))}))
- ([kiosk-id service-id]
- (let [service (NewPipe/getService service-id)
- extractor (doto (.getExtractorById (.getKioskList service) kiosk-id nil)
- (.fetchPage))
- info (KioskInfo/getInfo extractor)]
- {:id (.getId info)
- :url (.getUrl info)
- :service-id service-id
- :next-page (j/from-java (.getNextPage info))
- :related-streams (items/get-items (.getRelatedItems info))}))
- ([kiosk-id service-id page-url]
- (let [service (NewPipe/getService service-id)
- extractor (.getExtractorById (.getKioskList service) kiosk-id nil)
- url (url-decode page-url)
- kiosk-info (KioskInfo/getInfo extractor)
- info (KioskInfo/getMoreItems service (.getUrl kiosk-info) (Page. url))]
- {:next-page (j/from-java (.getNextPage info))
- :related-streams (items/get-items (.getItems info))})))
-
-(defn get-kiosks
- [service-id]
- (let [service (NewPipe/getService service-id)
- kiosks (.getKioskList service)]
- {:default-kiosk (.getDefaultKioskId kiosks)
- :available-kiosks (.getAvailableKiosks kiosks)}))
-
-(defn get-service
- [service]
- {:id (.getServiceId service)
- :info (j/from-java (.getServiceInfo service))
- :base-url (.getBaseUrl service)})
-
-(defn get-services
- []
- (map get-service (NewPipe/getServices)))
diff --git a/src/backend/tubo/api/streams.clj b/src/backend/tubo/api/streams.clj
deleted file mode 100644
index 6ce2086..0000000
--- a/src/backend/tubo/api/streams.clj
+++ /dev/null
@@ -1,36 +0,0 @@
-(ns tubo.api.streams
- (:require
- [clojure.java.data :as j]
- [ring.util.codec :refer [url-decode]]
- [tubo.api.items :as items])
- (:import
- org.schabi.newpipe.extractor.stream.StreamInfo
- org.schabi.newpipe.extractor.NewPipe
- org.schabi.newpipe.extractor.localization.DateWrapper
- java.time.Instant))
-
-(defn get-stream
- [url]
- (let [info (StreamInfo/getInfo (url-decode url))]
- {:name (.getName info)
- :url (.getUrl info)
- :description (.. info (getDescription) (getContent))
- :upload-date (.getTextualUploadDate info)
- :uploader-name (.getUploaderName info)
- :uploader-url (.getUploaderUrl info)
- :uploader-avatar (.getUploaderAvatarUrl info)
- :uploader-verified? (.isUploaderVerified info)
- :service-id (.getServiceId info)
- :thumbnail-url (.getThumbnailUrl info)
- :duration (.getDuration info)
- :tags (.getTags info)
- :category (.getCategory info)
- :view-count (when-not (= (.getViewCount info) -1) (.getViewCount info))
- :like-count (when-not (= (.getLikeCount info) -1) (.getLikeCount info))
- :dislike-count (when-not (= (.getDislikeCount info) -1) (.getDislikeCount info))
- :subscriber-count (when-not (= (.getUploaderSubscriberCount info) -1) (.getUploaderSubscriberCount info))
- :audio-streams (j/from-java (.getAudioStreams info))
- :video-streams (j/from-java (.getVideoStreams info))
- :hls-url (.getHlsUrl info)
- :dash-mpd-url (.getDashMpdUrl info)
- :related-streams (items/get-items (.getRelatedStreams info))}))