377 lines
9.1 KiB
Elm
377 lines
9.1 KiB
Elm
port module Video exposing
|
|
( Msg(..)
|
|
, Settings(..)
|
|
, SubtitleTrack
|
|
, Video
|
|
, fromConfig
|
|
, init
|
|
, nowHasQualities
|
|
, nowHasQuality
|
|
, nowHasSubtitleTrack
|
|
, nowHasSubtitles
|
|
, update
|
|
)
|
|
|
|
import Element exposing (Element)
|
|
import Json.Decode as Decode
|
|
import Video.Icons as Icons
|
|
import Video.Quality as Quality exposing (Quality)
|
|
|
|
|
|
type alias Video =
|
|
{ url : String
|
|
, id : String
|
|
, playing : Bool
|
|
, position : Float
|
|
, duration : Float
|
|
, loaded : List ( Float, Float )
|
|
, volume : Float
|
|
, muted : Bool
|
|
, isFullscreen : Bool
|
|
, quality : Maybe Quality.Quality
|
|
, qualities : List Int
|
|
, showBar : Bool
|
|
, animationFrame : Float
|
|
, size : ( Int, Int )
|
|
, playbackRate : Float
|
|
, settings : Settings
|
|
, showSettings : Bool
|
|
, subtitles : List SubtitleTrack
|
|
, subtitleTrack : Maybe SubtitleTrack
|
|
, showMiniature : Maybe ( Int, Int )
|
|
, showIcon : Maybe (Element Msg)
|
|
, showIconRequested : Maybe (Element Msg)
|
|
}
|
|
|
|
|
|
type alias Config =
|
|
{ url : String
|
|
, id : String
|
|
, autoplay : Bool
|
|
}
|
|
|
|
|
|
fromConfig : Config -> ( Video, Cmd Msg )
|
|
fromConfig config =
|
|
( { url = config.url
|
|
, id = config.id
|
|
, playing = False
|
|
, position = 0
|
|
, duration = 0
|
|
, loaded = []
|
|
, volume = 1
|
|
, muted = False
|
|
, isFullscreen = False
|
|
, quality = Nothing
|
|
, qualities = []
|
|
, showBar = True
|
|
, animationFrame = 0
|
|
, size = ( 0, 0 )
|
|
, playbackRate = 1
|
|
, settings = All
|
|
, showSettings = False
|
|
, subtitles = []
|
|
, subtitleTrack = Nothing
|
|
, showMiniature = Nothing
|
|
, showIcon = Nothing
|
|
, showIconRequested = Nothing
|
|
}
|
|
, init config.id config.url config.autoplay
|
|
)
|
|
|
|
|
|
type Settings
|
|
= All
|
|
| Speed
|
|
| Quality
|
|
| Subtitles
|
|
|
|
|
|
type alias SubtitleTrack =
|
|
{ name : String
|
|
, groupdId : String
|
|
, ty : String
|
|
, autoselect : Bool
|
|
, default : Bool
|
|
, forced : Bool
|
|
}
|
|
|
|
|
|
type Msg
|
|
= Noop
|
|
| PlayPause
|
|
| Seek Float
|
|
| ToggleSettings
|
|
| SetSettings Settings
|
|
| SetPlaybackRate Float
|
|
| SetQuality Quality.Quality
|
|
| SetSubtitleTrack Int
|
|
| SetVolume Float Bool
|
|
| RequestFullscreen
|
|
| ExitFullscreen
|
|
| AnimationFrameDelta Float
|
|
| MouseMove
|
|
| NowPlaying
|
|
| NowPaused
|
|
| NowHasDuration Float
|
|
| NowAtPosition Float
|
|
| NowAtVolume Float Bool
|
|
| NowLoaded (List ( Float, Float ))
|
|
| NowIsFullscreen Bool
|
|
| NowHasQualities (List Int)
|
|
| NowHasQuality Quality.Quality
|
|
| NowHasSize ( Int, Int )
|
|
| NowHasPlaybackRate Float
|
|
| NowHasSubtitles (List SubtitleTrack)
|
|
| NowHasSubtitleTrack (Maybe SubtitleTrack)
|
|
| NowHasMiniature (Maybe ( Int, Int ))
|
|
|
|
|
|
update : Msg -> Video -> ( Video, Cmd Msg )
|
|
update msg model =
|
|
case msg of
|
|
Noop ->
|
|
( model, Cmd.none )
|
|
|
|
PlayPause ->
|
|
( { model
|
|
| showIconRequested =
|
|
if model.playing then
|
|
Just (Icons.pause True)
|
|
|
|
else
|
|
Just (Icons.play True)
|
|
}
|
|
, playPause model.id
|
|
)
|
|
|
|
Seek time ->
|
|
( { model
|
|
| showIconRequested =
|
|
if time > model.position then
|
|
Just (Icons.fastForward True)
|
|
|
|
else
|
|
Just (Icons.rewind True)
|
|
}
|
|
, seek model.id time
|
|
)
|
|
|
|
SetPlaybackRate rate ->
|
|
( { model | showSettings = False, settings = All }, setPlaybackRate model.id rate )
|
|
|
|
ToggleSettings ->
|
|
( { model | showSettings = not model.showSettings }, Cmd.none )
|
|
|
|
SetSettings s ->
|
|
( { model | settings = s }, Cmd.none )
|
|
|
|
RequestFullscreen ->
|
|
( model, requestFullscreen model.id )
|
|
|
|
ExitFullscreen ->
|
|
( model, exitFullscreen model.id )
|
|
|
|
SetQuality q ->
|
|
( { model | showSettings = False, settings = All }, setQuality model.id q )
|
|
|
|
SetSubtitleTrack t ->
|
|
( { model | showSettings = False, settings = All }, setSubtitleTrack model.id t )
|
|
|
|
SetVolume v m ->
|
|
( { model
|
|
| showIconRequested =
|
|
if m then
|
|
Just (Icons.volumeX True)
|
|
|
|
else if v >= model.volume then
|
|
Just (Icons.volume2 True)
|
|
|
|
else
|
|
Just (Icons.volume1 True)
|
|
}
|
|
, setVolume model.id { volume = v, muted = m }
|
|
)
|
|
|
|
AnimationFrameDelta delta ->
|
|
let
|
|
animationFrame =
|
|
model.animationFrame + delta
|
|
|
|
( showSettings, settings ) =
|
|
if animationFrame > 3500 then
|
|
( False, All )
|
|
|
|
else
|
|
( model.showSettings, model.settings )
|
|
|
|
( showIconRequested, showIcon ) =
|
|
case ( model.showIconRequested, model.showIcon ) of
|
|
( Just a, Just b ) ->
|
|
( Just a, Nothing )
|
|
|
|
( Just a, Nothing ) ->
|
|
( Nothing, Just a )
|
|
|
|
( Nothing, a ) ->
|
|
( Nothing, a )
|
|
in
|
|
( { model
|
|
| animationFrame = animationFrame
|
|
, showSettings = showSettings
|
|
, settings = settings
|
|
, showIconRequested = showIconRequested
|
|
, showIcon = showIcon
|
|
}
|
|
, Cmd.none
|
|
)
|
|
|
|
MouseMove ->
|
|
( { model | animationFrame = 0 }, Cmd.none )
|
|
|
|
NowPlaying ->
|
|
( { model | playing = True }, Cmd.none )
|
|
|
|
NowPaused ->
|
|
( { model | playing = False }, Cmd.none )
|
|
|
|
NowHasDuration duration ->
|
|
( { model | duration = duration }, Cmd.none )
|
|
|
|
NowAtPosition position ->
|
|
( { model | position = position }, Cmd.none )
|
|
|
|
NowAtVolume volume muted ->
|
|
( { model | volume = volume, muted = muted }, Cmd.none )
|
|
|
|
NowLoaded loaded ->
|
|
( { model | loaded = loaded }, Cmd.none )
|
|
|
|
NowIsFullscreen fullscreen ->
|
|
( { model | isFullscreen = fullscreen }, Cmd.none )
|
|
|
|
NowHasQualities qualities ->
|
|
( { model | qualities = qualities }, Cmd.none )
|
|
|
|
NowHasQuality quality ->
|
|
( { model | quality = Just quality }, Cmd.none )
|
|
|
|
NowHasSize size ->
|
|
( { model | size = size }, Cmd.none )
|
|
|
|
NowHasPlaybackRate rate ->
|
|
( { model | playbackRate = rate }, Cmd.none )
|
|
|
|
NowHasSubtitles tracks ->
|
|
( { model | subtitles = tracks }, Cmd.none )
|
|
|
|
NowHasSubtitleTrack track ->
|
|
( { model | subtitleTrack = track }, Cmd.none )
|
|
|
|
NowHasMiniature miniature ->
|
|
( { model | showMiniature = miniature }, Cmd.none )
|
|
|
|
|
|
port polymnyVideoInit : ( String, String, Bool ) -> Cmd msg
|
|
|
|
|
|
init : String -> String -> Bool -> Cmd msg
|
|
init id url autoplay =
|
|
polymnyVideoInit ( id, url, autoplay )
|
|
|
|
|
|
port polymnyVideoPlayPause : String -> Cmd msg
|
|
|
|
|
|
playPause : String -> Cmd msg
|
|
playPause =
|
|
polymnyVideoPlayPause
|
|
|
|
|
|
port polymnyVideoSeek : ( String, Float ) -> Cmd msg
|
|
|
|
|
|
seek : String -> Float -> Cmd msg
|
|
seek id s =
|
|
polymnyVideoSeek ( id, s )
|
|
|
|
|
|
port polymnyVideoRequestFullscreen : String -> Cmd msg
|
|
|
|
|
|
requestFullscreen : String -> Cmd msg
|
|
requestFullscreen =
|
|
polymnyVideoRequestFullscreen
|
|
|
|
|
|
port polymnyVideoExitFullscreen : String -> Cmd msg
|
|
|
|
|
|
exitFullscreen : String -> Cmd msg
|
|
exitFullscreen =
|
|
polymnyVideoExitFullscreen
|
|
|
|
|
|
port polymnyVideoSetPlaybackRate : ( String, Float ) -> Cmd msg
|
|
|
|
|
|
setPlaybackRate : String -> Float -> Cmd msg
|
|
setPlaybackRate id playbackRate =
|
|
polymnyVideoSetPlaybackRate ( id, playbackRate )
|
|
|
|
|
|
port polymnyVideoSetQuality : ( String, Quality ) -> Cmd msg
|
|
|
|
|
|
setQuality : String -> Quality -> Cmd msg
|
|
setQuality id quality =
|
|
polymnyVideoSetQuality ( id, quality )
|
|
|
|
|
|
port polymnyVideoSetSubtitleTrack : ( String, Int ) -> Cmd msg
|
|
|
|
|
|
setSubtitleTrack : String -> Int -> Cmd msg
|
|
setSubtitleTrack id track =
|
|
polymnyVideoSetSubtitleTrack ( id, track )
|
|
|
|
|
|
port polymnyVideoSetVolume : ( String, { volume : Float, muted : Bool } ) -> Cmd msg
|
|
|
|
|
|
setVolume : String -> { volume : Float, muted : Bool } -> Cmd msg
|
|
setVolume id volume =
|
|
polymnyVideoSetVolume ( id, volume )
|
|
|
|
|
|
port polymnyVideoNowHasQualities : (List Int -> msg) -> Sub msg
|
|
|
|
|
|
nowHasQualities : (List Int -> msg) -> Sub msg
|
|
nowHasQualities =
|
|
polymnyVideoNowHasQualities
|
|
|
|
|
|
port polymnyVideoNowHasQuality : (Decode.Value -> msg) -> Sub msg
|
|
|
|
|
|
nowHasQuality : (Decode.Value -> msg) -> Sub msg
|
|
nowHasQuality =
|
|
polymnyVideoNowHasQuality
|
|
|
|
|
|
port polymnyVideoNowHasSubtitles : (Decode.Value -> msg) -> Sub msg
|
|
|
|
|
|
nowHasSubtitles : (Decode.Value -> msg) -> Sub msg
|
|
nowHasSubtitles =
|
|
polymnyVideoNowHasSubtitles
|
|
|
|
|
|
port polymnyVideoNowHasSubtitleTrack : (Decode.Value -> msg) -> Sub msg
|
|
|
|
|
|
nowHasSubtitleTrack : (Decode.Value -> msg) -> Sub msg
|
|
nowHasSubtitleTrack =
|
|
polymnyVideoNowHasSubtitleTrack
|