       (>! msg-ch (m/->SetPlaying false))
       stopped-at)))
 
-(defn start-event-loop!
+(defn start-event-loop
   "Main event loop of the Recording."
-  [{:keys [recording-ch-fn start-at speed loop?] :as source} command-ch msg-ch]
+  [{:keys [start-at speed loop? command-ch]} msg-ch data]
   (let [pri-ch (chan 10)]
     (go-loop [start-at start-at
               speed speed

        (condp = command
          :start (if stop-ch
                   (recur start-at speed end-ch stop-ch)
                   (do
                     (show-loading source msg-ch)
                     (let [{:keys [frames duration]} (<! (@recording-ch-fn true))
                           stop-ch (chan)
                           end-ch (play! msg-ch frames duration start-at speed loop? stop-ch)]
                       (recur nil speed end-ch stop-ch))))
          :stop (if stop-ch
                  (do
                    (close! stop-ch)

          :exit nil
          :internal/rewind (recur 0 speed nil nil)
          :internal/seek (let [start-at arg
                               {:keys [frames duration]} data
                               start-at (util/adjust-to-range start-at 0 duration)]
                           (>! msg-ch (m/->UpdateTime start-at))
                           (>! msg-ch (m/->UpdateScreen (screen-at start-at frames)))
                           (recur start-at speed end-ch stop-ch)))))))

(defn start-preloader [{:keys [recording-ch-fn command-ch force-load-ch preload? poster-time] :as recording} msg-ch]
  (go
    (let [recording-ch (recording-ch-fn (or preload? poster-time))
          [v c] (alts! [recording-ch force-load-ch])
          data (condp = c
                 recording-ch v
                 force-load-ch (do
                                 (>! msg-ch (m/->SetLoading true))
                                 (let [data (<! (recording-ch-fn true))]
                                   (>! msg-ch (m/->SetLoading false))
                                   data)))]
      (when poster-time
        (show-poster data poster-time msg-ch))
      (report-metadata data msg-ch)
      (start-event-loop recording msg-ch data))))

(defrecord Recording [recording-ch-fn command-ch force-load-ch start-at speed auto-play? loop? preload? poster-time]
  Source
  (init [this]
    (let [msg-ch (chan)]
      (start-preloader this msg-ch)
      (when auto-play?
        (start this))
      msg-ch))
  (close [this]
    (put! command-ch [:stop])
    (put! command-ch [:exit]))
  (start [this]
    (close! force-load-ch)
    (put! command-ch [:start]))
  (stop [this]
    (put! command-ch [:stop]))
  (toggle [this]
    (close! force-load-ch)
    (put! command-ch [:toggle]))
  (seek [this time]
    (close! force-load-ch)
    (put! command-ch [:seek time]))
  (change-speed [this speed]
    (put! command-ch [:change-speed speed])))
