aboutsummaryrefslogtreecommitdiff
path: root/src/frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/tau/components/player.cljs80
-rw-r--r--src/frontend/tau/views/stream.cljs13
2 files changed, 71 insertions, 22 deletions
diff --git a/src/frontend/tau/components/player.cljs b/src/frontend/tau/components/player.cljs
index 19f76bf..11cc9c5 100644
--- a/src/frontend/tau/components/player.cljs
+++ b/src/frontend/tau/components/player.cljs
@@ -1,24 +1,70 @@
(ns tau.components.player
(:require
+ [reagent.core :as r]
+ [reagent.dom :as rdom]
[re-frame.core :as rf]
[reitit.frontend.easy :as rfe]
- [tau.events :as events]))
+ [tau.events :as events]
+ ["video.js" :as videojs]))
(defn global-player
[]
- (let [{:keys [uploader-name uploader-url name stream url service-color]} @(rf/subscribe [:global-stream])
- show-global-player? @(rf/subscribe [:show-global-player])]
- (when show-global-player?
- [:div.sticky.bottom-0.z-50.bg-neutral-900.p-5.absolute
- {:style {:borderColor service-color :borderTopWidth "2px" :borderStyle "solid"}}
- [:div.flex.items-center.justify-between
- [:div.flex.flex-wrap.items-center
- [:div.flex.flex-col
- [:a.text-xs
- {:href (rfe/href :tau.router/stream nil {:url url})} name]
- [:a.text-xs.text-gray-300
- {:href (rfe/href :tau.router/channel nil {:url uploader-url})} uploader-name]]
- [:div.px-2.py-0.md:pt-4
- [:audio {:src stream :controls true}]]]
- [:div.px-2
- [:i.fa-solid.fa-close.cursor-pointer {:on-click #(rf/dispatch [::events/toggle-global-player])}]]]])))
+ (let [!player (r/atom nil)
+ !loop? (r/atom nil)]
+ (fn []
+ (let [{:keys [uploader-name uploader-url name stream url service-color]} @(rf/subscribe [:global-stream])
+ show-global-player? @(rf/subscribe [:show-global-player])]
+ (when show-global-player?
+ [:div.sticky.bottom-0.z-50.bg-neutral-900.p-5.absolute.box-border.m-0
+ {:style {:borderColor service-color :borderTopWidth "2px" :borderStyle "solid"}}
+ [:div.flex.items-center.justify-between
+ [:div.flex.flex-wrap.items-center
+ [:div.flex.flex-col
+ [:a.text-xs
+ {:href (rfe/href :tau.router/stream nil {:url url})} name]
+ [:a.text-xs.text-gray-300
+ {:href (rfe/href :tau.router/channel nil {:url uploader-url})} uploader-name]]
+ [:div.px-2.py-0.md:pt-4
+ [:audio {:src stream :ref #(reset! !player %) :loop @!loop?}]]
+ [:div.mx-2
+ [:button.focus:ring-transparent.mx-2
+ {:on-click (fn [] (swap! !loop? #(not %)))}
+ [:i.fa-solid.fa-repeat
+ {:style {:color (when @!loop? service-color)}}]]
+ [:button.focus:ring-transparent.mx-2
+ {:on-click #(when-let [player @!player]
+ (if (.-paused player)
+ (.play player)
+ (.pause player)))}
+ (if @!player
+ (if (.-paused @!player)
+ [:i.fa-solid.fa-play]
+ [:i.fa-solid.fa-pause])
+ [:i.fa-solid.fa-play])]]]
+ [:div.px-2
+ [:i.fa-solid.fa-close.cursor-pointer
+ {:on-click (fn []
+ (rf/dispatch [::events/toggle-global-player])
+ (.pause @!player))}]]]])))))
+
+(defn stream-player
+ [options url]
+ (let [!player (atom nil)]
+ (r/create-class
+ {:display-name "StreamPlayer"
+ :component-did-mount
+ (fn [this]
+ (reset! !player (videojs (rdom/dom-node this) (clj->js options))))
+ :component-did-update
+ (fn [this [_ prev-argv prev-more]]
+ (when (and @!player (not= prev-more (first (r/children this))))
+ (.src @!player (apply array (map #(js-obj "type" % "src" (first (r/children this)))
+ ["video/mp4" "video/webm"])))
+ (.ready @!player #(.play @!player))))
+ :component-will-unmount
+ (fn [_]
+ (when @!player
+ (.dispose @!player)))
+ :reagent-render
+ (fn [options url]
+ [:video-js.vjs-default-skin.vjs-big-play-centered.bottom-0.object-cover.min-h-full.max-h-full.min-w-full])})))
diff --git a/src/frontend/tau/views/stream.cljs b/src/frontend/tau/views/stream.cljs
index 78a1b1e..3363d6a 100644
--- a/src/frontend/tau/views/stream.cljs
+++ b/src/frontend/tau/views/stream.cljs
@@ -7,6 +7,7 @@
[tau.components.loading :as loading]
[tau.components.navigation :as navigation]
[tau.components.comments :as comments]
+ [tau.components.player :as player]
[tau.util :as util]))
(defn stream
@@ -27,11 +28,13 @@
[:div.w-full.pb-4.relative {:class "ml:w-4/5 xl:w-3/5"}
[navigation/back-button service-color]
[:div.flex.justify-center.relative
- {:style {:background (str "center / cover no-repeat url('" thumbnail-url"')")}
- :class "ml:h-[450px] lg:h-[600px]"}
- [:video.bottom-0.object-cover.min-h-full.max-h-full.min-w-full
- {:src content :controls true}
- "This browser can't play the stream format."]]
+ {:class "ml:h-[450px] lg:h-[600px]"}
+ (when stream-format
+ [player/stream-player {"sources" [{"src" content "type" "video/mp4"}
+ {"src" content "type" "video/webm"}]
+ "poster" thumbnail-url
+ "controls" true}
+ content])]
[:div.px-4.ml:p-0
[:div.flex.flex.w-full.mt-3
(when stream-format