Created
January 25, 2019 14:53
-
-
Save danabrams/8b986556e7b534f2ad4993988f6977f0 to your computer and use it in GitHub Desktop.
About the simplest possible Audio Player example for my Elm Media Control API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module AudioPlayer exposing (main) | |
import Browser | |
import Html exposing (..) | |
import Html.Events exposing (onClick) | |
import Media exposing (Setting(..), Source(..), changeSetting) | |
import Result exposing (Result(..)) | |
import Task exposing (Task) | |
type Msg | |
= CreatedMedia (Result Media.Error Media.Id) | |
| StateUpdated Media.State | |
| SettingChanged (Result Media.Error Media.State) | |
| ClickedPause | |
| ClickedPlay | |
type alias Model = | |
{ media : Maybe Media.Id, currentTime : Maybe Float } | |
main = | |
Browser.element { init = init, update = update, subscriptions = subscriptions, view = view } | |
init () = | |
( { media = Nothing, currentTime = Nothing } | |
, Task.attempt CreatedMedia <| | |
Media.create | |
{ sources = [ Url "https://mySite.com/myFile.mp3" ] | |
, loop = False | |
, autoplay = False | |
, muted = False | |
, volume = Nothing | |
} | |
) | |
subscriptions : Model -> Sub Msg | |
subscriptions model = | |
case model.media of | |
Just mediaId -> | |
Media.state StateUpdated mediaId | |
Nothing -> | |
Sub.none | |
update msg model = | |
case msg of | |
CreatedMedia result -> | |
case result of | |
Ok mediaId -> | |
( { model | media = Just mediaId }, Cmd.none ) | |
Err _ -> | |
( model, Cmd.none ) | |
SettingChanged result -> | |
case result of | |
Ok mediaState -> | |
( { model | currentTime = Just mediaState.currentTime }, Cmd.none ) | |
Err _ -> | |
( model, Cmd.none ) | |
StateUpdated mediaState -> | |
( { model | currentTime = Just mediaState.currentTime }, Cmd.none ) | |
ClickedPlay -> | |
case model.media of | |
Just mediaId -> | |
( model, Task.attempt SettingChanged <| changeSettings mediaId Play ) | |
Nothing -> | |
( model, Cmd.none ) | |
ClickedPause -> | |
case model.media of | |
Just mediaId -> | |
( model, Task.attempt SettingChanged <| changeSetting mediaId Pause ) | |
Nothing -> | |
( model, Cmd.none ) | |
view model = | |
let | |
status = | |
case model.currentTime of | |
Nothing -> | |
"No Media" | |
Just ct -> | |
"Current Time: " ++ String.fromFloat ct | |
in | |
div [] | |
[ text status | |
, button [ onClick ClickedPlay ] [ text "Play" ] | |
, button [ onClick ClickedPause ] [ text "Pause" ] | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Media exposing | |
( Id, create, Config, Source(..), state, State, Error | |
, changeSetting, Setting(..) | |
, video | |
) | |
{-| | |
# Media | |
@docs Id, create, Config, Source, state, State, Error, TimeRange | |
# Settings | |
@docs changeSetting, Setting | |
# Dom | |
@docs video | |
-} | |
import Html exposing (Attribute, Html) | |
import Task exposing (Task) | |
{-| Create a new piece of media that you can then play or otherwise manipulate. | |
-} | |
create : Config -> Task Error Id | |
create = | |
Debug.todo "create media not implemented" | |
{-| Change a setting on your media, like changing the Volume or Pausing it. | |
-} | |
changeSetting : Id -> Setting -> Task Error State | |
changeSetting mediaId = | |
Debug.todo "setState not implemented" | |
{-| A subscription to the current State of your media. NOTE: In final implementation, we'll probably need to make a "WithOptions" version for some advanced use-cases. | |
-} | |
state : (State -> msg) -> Id -> Sub msg | |
state mediaId msg = | |
Debug.todo "media state subscription not yet implemented" | |
{-| Create a visible Html Dom node using your video Id. | |
-} | |
video : Id -> List (Html attribute) -> Html msg | |
video mediaId attrs = | |
Debug.todo "video function not implemented" | |
{-| This is the key type. It stores a reference to your media that you pass to the Tasks in this package. You need to create it before you can do anything. | |
-} | |
type Id | |
= Id Int | |
{-| A work in progress enumeration of all the possible errors | |
-} | |
type Error | |
= InvalidSetting | |
| InvalidSource | |
| SettingAgainstBrowserPolicy | |
| NetworkConnectivity | |
{-| An example of what a State record might look like | |
-} | |
type alias State = | |
{ currentTime : Float | |
, duration : Float | |
, playback : Playback | |
, source : Source | |
, loop : Bool | |
, muted : Bool | |
, volume : Int | |
, buffered : List TimeRange | |
, seekable : List TimeRange | |
, played : List TimeRange | |
, textTracks : List String | |
} | |
{-| A time range is a range of time withing the media, for instance, 0:03 to 0:15. | |
-} | |
type alias TimeRange = | |
{ start : Float, end : Float } | |
{-| Current status of media playback | |
-} | |
type Playback | |
= Playing | |
| Paused | |
| Ended | |
| PlaybackError String | |
{-| Where is the media file you want to play. In the future, we can add other source types, like webcams, or webRTC video chats, etc. | |
-} | |
type Source | |
= Url String | |
{-| This is how you configure your media when you create it. It takes a list of sources because best practice to include fallback versions using different codecs. NOTE: You would probably also define things like TextTracks (subtitles) in here. | |
-} | |
type alias Config = | |
{ sources : List Source | |
, loop : Bool | |
, autoplay : Bool | |
, muted : Bool | |
, volume : Maybe Float | |
} | |
{-| These are the settings you can (attempt to) change the state of media. NOTE: This is a simple set, there are some more dealing with things like TextTracks, but I think these give the idea. | |
-} | |
type Setting | |
= Play | |
| Pause | |
| Seek Float | |
| SetSource Source | |
| Mute | |
| Unmute | |
| SetVolume Int | |
| Loop | |
| NoLoop | |
| Autoplay |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment