elm-video/src/Video.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