diff --git a/README.md b/README.md index 9d99b9fd..6ccbc7d7 100644 --- a/README.md +++ b/README.md @@ -239,6 +239,28 @@ document.getElementById('player').currentTime = 33; ### Events +#### loadedmetadata, loadeddata, canplay, canplaythrough + +The `loadedmetadata`, `loadeddata`, `canplay` and `canplaythrough` events are +fired (all of them, in this order) when the recording has been loaded and is +ready to play. The recordings are always fully fetched (you can't partially load +JSON) so there's no difference in the amount of metadata/data available between +these 4 events - when either event occurs the player already has all the +information for smooth playback. In other words, it's enough to listen to only +one of them, e.g. `canplaythrough` (all 4 are supported to make it more in line +with HTMLVideoElement). + +```javascript +document.getElementById('player').addEventListener('canplaythrough, function(e) { + console.log("all ready to play"); +} +``` + +NOTE: The player starts fetching the recording either when `preload` attribute +is set (in this case these events may not be immediately followed by `play` +event), or when user starts the playback (in this case these events are +immediately followed by `play` event). + #### play The `play` event is fired when playback has begun. diff --git a/resources/public/element.html b/resources/public/element.html index 3af39bc8..810a7a7b 100644 --- a/resources/public/element.html +++ b/resources/public/element.html @@ -19,6 +19,22 @@ /* this.currentTime = 33;*/ }) + player.addEventListener('loadedmetadata', function(e) { + console.log('got "loadedmetadata" event'); + }) + + player.addEventListener('loadeddata', function(e) { + console.log('got "loadeddata" event'); + }) + + player.addEventListener('canplay', function(e) { + console.log('got "canplay" event'); + }) + + player.addEventListener('canplaythrough', function(e) { + console.log('got "canplaythrough" event'); + }) + player.addEventListener('play', function(e) { console.log('got "play" event'); console.log("we're at", this.currentTime); diff --git a/resources/public/element.js b/resources/public/element.js index 5a083449..ce246cf7 100644 --- a/resources/public/element.js +++ b/resources/public/element.js @@ -45,8 +45,20 @@ function registerAsciinemaPlayerElement() { this.opt('author-url', 'authorURL'), this.opt('author-img-url', 'authorImgURL'), { - onPlay: function() { self.dispatchEvent(new CustomEvent("play")); }, - onPause: function() { self.dispatchEvent(new CustomEvent("pause")); } + onCanPlay: function() { + self.dispatchEvent(new CustomEvent("loadedmetadata")); + self.dispatchEvent(new CustomEvent("loadeddata")); + self.dispatchEvent(new CustomEvent("canplay")); + self.dispatchEvent(new CustomEvent("canplaythrough")); + }, + + onPlay: function() { + self.dispatchEvent(new CustomEvent("play")); + }, + + onPause: function() { + self.dispatchEvent(new CustomEvent("pause")); + } } ); diff --git a/src/asciinema/player/core.cljs b/src/asciinema/player/core.cljs index 1fc9aa65..698f417d 100644 --- a/src/asciinema/player/core.cljs +++ b/src/asciinema/player/core.cljs @@ -79,7 +79,8 @@ :font-size font-size :theme theme :show-hud false} - (select-keys options [:title :author :author-url :author-img-url :on-play :on-pause])))) + (select-keys options [:title :author :author-url :author-img-url + :on-can-play :on-play :on-pause])))) (defn make-player-ratom "Returns Reagent atom with initial player state." diff --git a/src/asciinema/player/js.cljs b/src/asciinema/player/js.cljs index 88b33cf0..049b0f3d 100644 --- a/src/asciinema/player/js.cljs +++ b/src/asciinema/player/js.cljs @@ -15,6 +15,7 @@ :authorURL :author-url :startAt :start-at :authorImgURL :author-img-url + :onCanPlay :on-can-play :onPlay :on-play :onPause :on-pause})) player (p/create-player dom-node url options)] diff --git a/src/asciinema/player/messages.cljs b/src/asciinema/player/messages.cljs index 3bdec199..19f21801 100644 --- a/src/asciinema/player/messages.cljs +++ b/src/asciinema/player/messages.cljs @@ -28,14 +28,14 @@ ;;; Source originated messages -(defrecord Resize [width height]) - -(defrecord SetDuration [duration]) +(defrecord SetMetadata [width height duration]) (defrecord SetLoading [loading]) (defrecord SetPlaying [playing]) +(defrecord TriggerCanPlay []) + (defrecord UpdateScreen [screen]) (defrecord UpdateTime [time]) diff --git a/src/asciinema/player/processing.cljs b/src/asciinema/player/processing.cljs index 8e69bc93..300f7f88 100644 --- a/src/asciinema/player/processing.cljs +++ b/src/asciinema/player/processing.cljs @@ -66,20 +66,23 @@ ;;; Source originated messages (extend-protocol m/Update - m/Resize - (update-player [this {player-width :width player-height :height :as player}] - (-> player - (assoc :width (or player-width (:width this))) - (assoc :height (or player-height (:height this))))) - - m/SetDuration - (update-player [this player] - (assoc player :duration (:duration this))) + m/SetMetadata + (update-player [{:keys [width height duration]} {player-width :width player-height :height :as player}] + (assoc player + :width (or player-width width) + :height (or player-height height) + :duration duration)) m/SetLoading (update-player [this player] (assoc player :loading (:loading this))) + m/TriggerCanPlay + (update-player [this {:keys [on-can-play] :as player}] + (when on-can-play + (on-can-play)) + player) + m/UpdateTime (update-player [this player] (assoc player :current-time (:time this)))) diff --git a/src/asciinema/player/source.cljs b/src/asciinema/player/source.cljs index b42b8535..da5c86c3 100644 --- a/src/asciinema/player/source.cljs +++ b/src/asciinema/player/source.cljs @@ -87,14 +87,14 @@ :handler #(deliver (recording-fn %)) :error-handler #(println %)})))) -(defn report-duration-and-size +(defn report-metadata "Waits for recording to load and then reports its size and duration to the player." [{:keys [recording-ch-fn]} msg-ch] (go (let [{:keys [duration width height]} (! msg-ch (m/->SetDuration duration)) - (>! msg-ch (m/->Resize width height))))) + (>! msg-ch (m/->SetMetadata width height duration)) + (>! msg-ch (m/->TriggerCanPlay))))) (defn show-poster "Forces loading of recording and sends 'poster' at a given time to the @@ -226,7 +226,7 @@ (reset! command-ch (start-event-loop! this msg-ch)) (let [f (make-recording-ch-fn url recording-fn)] (reset! recording-ch-fn f) - (report-duration-and-size this msg-ch)) + (report-metadata this msg-ch)) (when preload? (@recording-ch-fn true)) (if auto-play?