rui_orig/mediaPlayer.go

1638 lines
46 KiB
Go
Raw Permalink Normal View History

2021-09-07 17:36:50 +03:00
package rui
import (
"fmt"
"math"
"strconv"
"strings"
)
// Constants which related to media player properties and events
2021-09-07 17:36:50 +03:00
const (
// Controls is the constant for "controls" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Controls whether the browser need to provide controls to allow user to control audio playback, volume, seeking and
// pause/resume playback. Default value is `false`.
//
// Supported types: `bool`, `int`, `string`.
//
// Values:
// `true` or `1` or "true", "yes", "on", "1" - The browser will offer controls to allow the user to control audio playback, volume, seeking and pause/resume playback.
// `false` or `0` or "false", "no", "off", "0" - No controls will be visible to the end user.
//
// Usage in `VideoPlayer`:
// Whether the browser need to provide controls to allow user to control video playback, volume, seeking and pause/resume
// playback. Default value is `false`.
//
// Supported types: `bool`, `int`, `string`.
//
// Values:
// `true` or `1` or "true", "yes", "on", "1" - The browser will offer controls to allow the user to control video playback, volume, seeking and pause/resume playback.
// `false` or `0` or "false", "no", "off", "0" - No controls will be visible to the end user.
2021-09-07 17:36:50 +03:00
Controls = "controls"
2024-04-23 19:34:36 +03:00
// Loop is the constant for "loop" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Controls whether the audio player will play media in a loop. Default value is `false`.
//
// Supported types: `bool`, `int`, `string`.
//
// Values:
// `true` or `1` or "true", "yes", "on", "1" - The audio player will automatically seek back to the start upon reaching the end of the audio.
// `false` or `0` or "false", "no", "off", "0" - Audio player will stop playing when the end of the media file has been reached.
//
// Usage in `VideoPlayer`:
// Controls whether the video player will play media in a loop. Default value is `false`.
//
// Supported types: `bool`, `int`, `string`.
//
// Values:
// `true` or `1` or "true", "yes", "on", "1" - The video player will automatically seek back to the start upon reaching the end of the video.
// `false` or `0` or "false", "no", "off", "0" - Video player will stop playing when the end of the media file has been reached.
2021-09-07 17:36:50 +03:00
Loop = "loop"
2024-04-23 19:34:36 +03:00
// Muted is the constant for "muted" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Controls whether the audio will be initially silenced. Default value is `false`.
//
// Supported types: `bool`, `int`, `string`.
//
// Values:
// `true` or `1` or "true", "yes", "on", "1" - Audio will be muted.
// `false` or `0` or "false", "no", "off", "0" - Audio playing normally.
//
// Usage in `VideoPlayer`:
// Controls whether the video will be initially silenced. Default value is `false`.
//
// Supported types: `bool`, `int`, `string`.
//
// Values:
// `true` or `1` or "true", "yes", "on", "1" - Video will be muted.
// `false` or `0` or "false", "no", "off", "0" - Video playing normally.
2021-09-07 17:36:50 +03:00
Muted = "muted"
2024-04-23 19:34:36 +03:00
// Preload is the constant for "preload" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Property is intended to provide a hint to the browser about what the author thinks will lead to the best user
// experience. Default value is different for each browser.
//
// Supported types: `int`, `string`.
//
// Values:
// `0`(`PreloadNone`) or "none" - Media file must not be pre-loaded.
// `1`(`PreloadMetadata`) or "metadata" - Only metadata is preloaded.
// `2`(`PreloadAuto`) or "auto" - The entire media file can be downloaded even if the user doesn't have to use it.
//
// Usage in `VideoPlayer`:
// Property is intended to provide a hint to the browser about what the author thinks will lead to the best user
// experience. Default value is different for each browser.
//
// Supported types: `int`, `string`.
//
// Values:
// `0`(`PreloadNone`) or "none" - Media file must not be pre-loaded.
// `1`(`PreloadMetadata`) or "metadata" - Only metadata is preloaded.
// `2`(`PreloadAuto`) or "auto" - The entire media file can be downloaded even if the user doesn't have to use it.
2021-09-07 17:36:50 +03:00
Preload = "preload"
// AbortEvent is the constant for "abort-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Fired when the resource was not fully loaded, but not as the result of an error.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Fired when the resource was not fully loaded, but not as the result of an error.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
AbortEvent = "abort-event"
2024-04-23 19:34:36 +03:00
// CanPlayEvent is the constant for "can-play-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the browser can play the media, but estimates that not enough data has been loaded to play the media up to
// its end without having to stop for further buffering of content.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the browser can play the media, but estimates that not enough data has been loaded to play the media up to
// its end without having to stop for further buffering of content.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
CanPlayEvent = "can-play-event"
2024-04-23 19:34:36 +03:00
// CanPlayThroughEvent is the constant for "can-play-through-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the browser estimates it can play the media up to its end without stopping for content buffering.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the browser estimates it can play the media up to its end without stopping for content buffering.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
CanPlayThroughEvent = "can-play-through-event"
2024-04-23 19:34:36 +03:00
// CompleteEvent is the constant for "complete-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the rendering of an OfflineAudioContext has been terminated.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the rendering of an OfflineAudioContext has been terminated.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
CompleteEvent = "complete-event"
2024-04-23 19:34:36 +03:00
// DurationChangedEvent is the constant for "duration-changed-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the duration attribute has been updated.
//
// General listener format:
// `func(player rui.MediaPlayer, duration float64)`.
//
// where:
// player - Interface of a player which generated this event,
// duration - Current duration.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(duration float64)`,
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the duration attribute has been updated.
//
// General listener format:
// `func(player rui.MediaPlayer, duration float64)`.
//
// where:
// player - Interface of a player which generated this event,
// duration - Current duration.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(duration float64)`,
// `func()`.
2021-09-07 17:36:50 +03:00
DurationChangedEvent = "duration-changed-event"
2024-04-23 19:34:36 +03:00
// EmptiedEvent is the constant for "emptied-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the media has become empty; for example, this event is sent if the media has already been loaded(or
// partially loaded), and the HTMLMediaElement.load method is called to reload it.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the media has become empty; for example, this event is sent if the media has already been loaded(or
// partially loaded), and the HTMLMediaElement.load method is called to reload it.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
EmptiedEvent = "emptied-event"
2024-04-23 19:34:36 +03:00
// EndedEvent is the constant for "ended-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the playback has stopped because the end of the media was reached.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the playback has stopped because the end of the media was reached.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
EndedEvent = "ended-event"
2024-04-23 19:34:36 +03:00
// LoadedDataEvent is the constant for "loaded-data-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the first frame of the media has finished loading.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the first frame of the media has finished loading.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
LoadedDataEvent = "loaded-data-event"
2024-04-23 19:34:36 +03:00
// LoadedMetadataEvent is the constant for "loaded-metadata-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the metadata has been loaded.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the metadata has been loaded.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
LoadedMetadataEvent = "loaded-metadata-event"
2024-04-23 19:34:36 +03:00
// LoadStartEvent is the constant for "load-start-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Fired when the browser has started to load a resource.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Fired when the browser has started to load a resource.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
LoadStartEvent = "load-start-event"
2024-04-23 19:34:36 +03:00
// PauseEvent is the constant for "pause-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the playback has been paused.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the playback has been paused.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
PauseEvent = "pause-event"
2024-04-23 19:34:36 +03:00
// PlayEvent is the constant for "play-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the playback has begun.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the playback has begun.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
PlayEvent = "play-event"
2024-04-23 19:34:36 +03:00
// PlayingEvent is the constant for "playing-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the playback is ready to start after having been paused or delayed due to lack of data.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the playback is ready to start after having been paused or delayed due to lack of data.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
PlayingEvent = "playing-event"
2024-04-23 19:34:36 +03:00
// ProgressEvent is the constant for "progress-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Fired periodically as the browser loads a resource.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Fired periodically as the browser loads a resource.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
ProgressEvent = "progress-event"
2024-04-23 19:34:36 +03:00
// RateChangedEvent is the constant for "rate-changed-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the playback rate has changed.
//
// General listener format:
// `func(player rui.MediaPlayer, rate float64)`.
//
// where:
// player - Interface of a player which generated this event,
// rate - Playback rate.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(rate float64)`,
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the playback rate has changed.
//
// General listener format:
// `func(player rui.MediaPlayer, rate float64)`.
//
// where:
// player - Interface of a player which generated this event,
// rate - Playback rate.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(rate float64)`,
// `func()`.
2021-09-07 17:36:50 +03:00
RateChangedEvent = "rate-changed-event"
2024-04-23 19:34:36 +03:00
// SeekedEvent is the constant for "seeked-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when a seek operation completed.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when a seek operation completed.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
SeekedEvent = "seeked-event"
2024-04-23 19:34:36 +03:00
// SeekingEvent is the constant for "seeking-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when a seek operation has began.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when a seek operation has began.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
SeekingEvent = "seeking-event"
2024-04-23 19:34:36 +03:00
// StalledEvent is the constant for "stalled-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the user agent is trying to fetch media data, but data is unexpectedly not forthcoming.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the user agent is trying to fetch media data, but data is unexpectedly not forthcoming.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
StalledEvent = "stalled-event"
2024-04-23 19:34:36 +03:00
// SuspendEvent is the constant for "suspend-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the media data loading has been suspended.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the media data loading has been suspended.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
SuspendEvent = "suspend-event"
2024-04-23 19:34:36 +03:00
// TimeUpdateEvent is the constant for "time-update-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the time indicated by the currentTime attribute has been updated.
//
// General listener format:
// `func(player rui.MediaPlayer, time float64)`.
//
// where:
// player - Interface of a player which generated this event,
// time - Current time.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(time float64)`,
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the time indicated by the currentTime attribute has been updated.
//
// General listener format:
// `func(player rui.MediaPlayer, time float64)`.
//
// where:
// player - Interface of a player which generated this event,
// time - Current time.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(time float64)`,
// `func()`.
2021-09-07 17:36:50 +03:00
TimeUpdateEvent = "time-update-event"
2024-04-23 19:34:36 +03:00
// VolumeChangedEvent is the constant for "volume-changed-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the volume has changed.
//
// General listener format:
// `func(player rui.MediaPlayer, volume float64)`.
//
// where:
// player - Interface of a player which generated this event,
// volume - New volume level.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(volume float64)`,
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the volume has changed.
//
// General listener format:
// `func(player rui.MediaPlayer, volume float64)`.
//
// where:
// player - Interface of a player which generated this event,
// volume - New volume level.
//
// Allowed listener formats:
// `func(player rui.MediaPlayer)`,
// `func(volume float64)`,
// `func()`.
2021-09-07 17:36:50 +03:00
VolumeChangedEvent = "volume-changed-event"
2024-04-23 19:34:36 +03:00
// WaitingEvent is the constant for "waiting-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Occur when the playback has stopped because of a temporary lack of data.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
//
// Usage in `VideoPlayer`:
// Occur when the playback has stopped because of a temporary lack of data.
//
// General listener format:
// `func(player rui.MediaPlayer)`.
//
// where:
// player - Interface of a player which generated this event.
//
// Allowed listener formats:
// `func()`.
2021-09-07 17:36:50 +03:00
WaitingEvent = "waiting-event"
2024-04-23 19:34:36 +03:00
// PlayerErrorEvent is the constant for "player-error-event" property tag.
//
// Used by `AudioPlayer`, `VideoPlayer`.
//
// Usage in `AudioPlayer`:
// Fired when the resource could not be loaded due to an error(for example, a network connectivity problem).
//
// General listener format:
// `func(player rui.MediaPlayer, code int, message string)`.
//
// where:
// player - Interface of a player which generated this event,
// code - Error code. See below,
// message - Error message,
// Error codes:
// `0`(`PlayerErrorUnknown`) - Unknown error,
// `1`(`PlayerErrorAborted`) - Fetching the associated resource was interrupted by a user request,
// `2`(`PlayerErrorNetwork`) - Some kind of network error has occurred that prevented the media from successfully ejecting, even though it was previously available,
// `3`(`PlayerErrorDecode`) - Although the resource was previously identified as being used, an error occurred while trying to decode the media resource,
// `4`(`PlayerErrorSourceNotSupported`) - The associated resource object or media provider was found to be invalid.
//
// Allowed listener formats:
// `func(code int, message string)`,
// `func(player rui.MediaPlayer)`,
// `func()`.
//
// Usage in `VideoPlayer`:
// Fired when the resource could not be loaded due to an error(for example, a network connectivity problem).
//
// General listener format:
// `func(player rui.MediaPlayer, code int, message string)`.
//
// where:
// player - Interface of a player which generated this event,
// code - Error code. See below,
// message - Error message,
// Error codes:
// `0`(`PlayerErrorUnknown`) - Unknown error,
// `1`(`PlayerErrorAborted`) - Fetching the associated resource was interrupted by a user request,
// `2`(`PlayerErrorNetwork`) - Some kind of network error has occurred that prevented the media from successfully ejecting, even though it was previously available,
// `3`(`PlayerErrorDecode`) - Although the resource was previously identified as being used, an error occurred while trying to decode the media resource,
// `4`(`PlayerErrorSourceNotSupported`) - The associated resource object or media provider was found to be invalid.
//
// Allowed listener formats:
// `func(code int, message string)`,
// `func(player rui.MediaPlayer)`,
// `func()`.
2021-09-07 17:36:50 +03:00
PlayerErrorEvent = "player-error-event"
// PreloadNone - value of the view "preload" property: indicates that the audio/video should not be preloaded.
PreloadNone = 0
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// PreloadMetadata - value of the view "preload" property: indicates that only audio/video metadata (e.g. length) is fetched.
PreloadMetadata = 1
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// PreloadAuto - value of the view "preload" property: indicates that the whole audio file can be downloaded,
// even if the user is not expected to use it.
PreloadAuto = 2
// PlayerErrorUnknown - MediaPlayer error code: An unknown error.
PlayerErrorUnknown = 0
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// PlayerErrorAborted - MediaPlayer error code: The fetching of the associated resource was aborted by the user's request.
PlayerErrorAborted = 1
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// PlayerErrorNetwork - MediaPlayer error code: Some kind of network error occurred which prevented the media
// from being successfully fetched, despite having previously been available.
PlayerErrorNetwork = 2
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// PlayerErrorDecode - MediaPlayer error code: Despite having previously been determined to be usable,
// an error occurred while trying to decode the media resource, resulting in an error.
PlayerErrorDecode = 3
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// PlayerErrorSourceNotSupported - MediaPlayer error code: The associated resource or media provider object has been found to be unsuitable.
PlayerErrorSourceNotSupported = 4
)
// MediaPlayer is a common interface for media player views like [AudioPlayer] and [VideoPlayer].
2021-09-07 17:36:50 +03:00
type MediaPlayer interface {
View
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// Play attempts to begin playback of the media.
Play()
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// Pause will pause playback of the media, if the media is already in a paused state this method will have no effect.
Pause()
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// SetCurrentTime sets the current playback time in seconds.
SetCurrentTime(seconds float64)
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// CurrentTime returns the current playback time in seconds.
CurrentTime() float64
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// Duration returns the value indicating the total duration of the media in seconds.
// If no media data is available, the returned value is NaN.
Duration() float64
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// SetPlaybackRate sets the rate at which the media is being played back. This is used to implement user controls
// for fast forward, slow motion, and so forth. The normal playback rate is multiplied by this value to obtain
// the current rate, so a value of 1.0 indicates normal speed.
SetPlaybackRate(rate float64)
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// PlaybackRate returns the rate at which the media is being played back.
PlaybackRate() float64
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// SetVolume sets the audio volume, from 0.0 (silent) to 1.0 (loudest).
SetVolume(volume float64)
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// Volume returns the audio volume, from 0.0 (silent) to 1.0 (loudest).
Volume() float64
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// IsEnded function tells whether the media element is ended.
IsEnded() bool
2024-04-23 19:34:36 +03:00
2021-09-07 17:36:50 +03:00
// IsPaused function tells whether the media element is paused.
IsPaused() bool
}
type mediaPlayerData struct {
viewData
}
// MediaSource represent one media file source
2021-09-07 17:36:50 +03:00
type MediaSource struct {
// Url of the source
Url string
// MimeType of the source
2021-09-07 17:36:50 +03:00
MimeType string
}
func (player *mediaPlayerData) init(session Session) {
player.viewData.init(session)
2021-09-07 17:36:50 +03:00
player.tag = "MediaPlayer"
}
2022-05-22 12:54:02 +03:00
func (player *mediaPlayerData) String() string {
return getViewString(player, nil)
2022-05-22 12:54:02 +03:00
}
func (player *mediaPlayerData) Focusable() bool {
return true
}
2021-09-07 17:36:50 +03:00
func (player *mediaPlayerData) Remove(tag string) {
player.remove(strings.ToLower(tag))
}
func (player *mediaPlayerData) remove(tag string) {
player.viewData.remove(tag)
player.propertyChanged(tag)
2021-09-07 17:36:50 +03:00
}
2022-07-26 18:36:00 +03:00
func (player *mediaPlayerData) Set(tag string, value any) bool {
2021-09-07 17:36:50 +03:00
return player.set(strings.ToLower(tag), value)
}
2022-07-26 18:36:00 +03:00
func (player *mediaPlayerData) set(tag string, value any) bool {
2021-09-07 17:36:50 +03:00
if value == nil {
player.remove(tag)
return true
}
switch tag {
case Controls, Loop, Muted, Preload:
if player.viewData.set(tag, value) {
player.propertyChanged(tag)
return true
}
case AbortEvent, CanPlayEvent, CanPlayThroughEvent, CompleteEvent, EmptiedEvent, LoadStartEvent,
EndedEvent, LoadedDataEvent, LoadedMetadataEvent, PauseEvent, PlayEvent, PlayingEvent,
ProgressEvent, SeekedEvent, SeekingEvent, StalledEvent, SuspendEvent, WaitingEvent:
2022-07-27 20:31:57 +03:00
if listeners, ok := valueToNoParamListeners[MediaPlayer](value); ok {
2021-09-07 17:36:50 +03:00
if listeners == nil {
delete(player.properties, tag)
} else {
player.properties[tag] = listeners
}
player.propertyChanged(tag)
player.propertyChangedEvent(tag)
2021-09-07 17:36:50 +03:00
return true
}
notCompatibleType(tag, value)
case DurationChangedEvent, RateChangedEvent, TimeUpdateEvent, VolumeChangedEvent:
2022-07-27 20:31:57 +03:00
if listeners, ok := valueToEventListeners[MediaPlayer, float64](value); ok {
2021-09-07 17:36:50 +03:00
if listeners == nil {
delete(player.properties, tag)
} else {
player.properties[tag] = listeners
}
player.propertyChanged(tag)
player.propertyChangedEvent(tag)
2021-09-07 17:36:50 +03:00
return true
}
notCompatibleType(tag, value)
case PlayerErrorEvent:
if listeners, ok := valueToPlayerErrorListeners(value); ok {
if listeners == nil {
delete(player.properties, tag)
} else {
player.properties[tag] = listeners
}
player.propertyChanged(tag)
player.propertyChangedEvent(tag)
2021-09-07 17:36:50 +03:00
return true
}
notCompatibleType(tag, value)
case Source:
if player.setSource(value) {
player.propertyChanged(tag)
player.propertyChangedEvent(tag)
2021-09-07 17:36:50 +03:00
return true
}
default:
return player.viewData.set(tag, value)
2021-09-07 17:36:50 +03:00
}
2021-09-07 17:36:50 +03:00
return false
}
2022-07-26 18:36:00 +03:00
func (player *mediaPlayerData) setSource(value any) bool {
2021-09-07 17:36:50 +03:00
switch value := value.(type) {
case string:
src := MediaSource{Url: value, MimeType: ""}
player.properties[Source] = []MediaSource{src}
case MediaSource:
player.properties[Source] = []MediaSource{value}
case []MediaSource:
player.properties[Source] = value
case DataObject:
url, ok := value.PropertyValue("src")
if !ok || url == "" {
invalidPropertyValue(Source, value)
return false
}
mimeType, _ := value.PropertyValue("mime-type")
src := MediaSource{Url: url, MimeType: mimeType}
player.properties[Source] = []MediaSource{src}
case []DataValue:
src := []MediaSource{}
for _, val := range value {
if val.IsObject() {
obj := val.Object()
if url, ok := obj.PropertyValue("src"); ok && url != "" {
mimeType, _ := obj.PropertyValue("mime-type")
src = append(src, MediaSource{Url: url, MimeType: mimeType})
} else {
invalidPropertyValue(Source, value)
return false
}
} else {
src = append(src, MediaSource{Url: val.Value(), MimeType: ""})
}
}
if len(src) == 0 {
invalidPropertyValue(Source, value)
return false
}
player.properties[Source] = src
default:
notCompatibleType(Source, value)
return false
}
return true
}
2022-07-26 18:36:00 +03:00
func valueToPlayerErrorListeners(value any) ([]func(MediaPlayer, int, string), bool) {
2021-09-07 17:36:50 +03:00
if value == nil {
return nil, true
}
switch value := value.(type) {
case func(MediaPlayer, int, string):
return []func(MediaPlayer, int, string){value}, true
case func(int, string):
2022-07-19 18:22:19 +03:00
fn := func(_ MediaPlayer, code int, message string) {
2021-09-07 17:36:50 +03:00
value(code, message)
}
return []func(MediaPlayer, int, string){fn}, true
case func(MediaPlayer):
2022-07-19 18:22:19 +03:00
fn := func(player MediaPlayer, _ int, _ string) {
2021-09-07 17:36:50 +03:00
value(player)
}
return []func(MediaPlayer, int, string){fn}, true
case func():
2022-07-19 18:22:19 +03:00
fn := func(MediaPlayer, int, string) {
2021-09-07 17:36:50 +03:00
value()
}
return []func(MediaPlayer, int, string){fn}, true
case []func(MediaPlayer, int, string):
if len(value) == 0 {
return nil, true
}
for _, fn := range value {
if fn == nil {
return nil, false
}
}
return value, true
case []func(int, string):
count := len(value)
if count == 0 {
return nil, true
}
listeners := make([]func(MediaPlayer, int, string), count)
for i, v := range value {
if v == nil {
return nil, false
}
2022-07-19 18:22:19 +03:00
listeners[i] = func(_ MediaPlayer, code int, message string) {
2021-09-07 17:36:50 +03:00
v(code, message)
}
}
return listeners, true
case []func(MediaPlayer):
count := len(value)
if count == 0 {
return nil, true
}
listeners := make([]func(MediaPlayer, int, string), count)
for i, v := range value {
if v == nil {
return nil, false
}
2022-07-19 18:22:19 +03:00
listeners[i] = func(player MediaPlayer, _ int, _ string) {
2021-09-07 17:36:50 +03:00
v(player)
}
}
return listeners, true
case []func():
count := len(value)
if count == 0 {
return nil, true
}
listeners := make([]func(MediaPlayer, int, string), count)
for i, v := range value {
if v == nil {
return nil, false
}
2022-07-19 18:22:19 +03:00
listeners[i] = func(MediaPlayer, int, string) {
2021-09-07 17:36:50 +03:00
v()
}
}
return listeners, true
2022-07-26 18:36:00 +03:00
case []any:
2021-09-07 17:36:50 +03:00
count := len(value)
if count == 0 {
return nil, true
}
listeners := make([]func(MediaPlayer, int, string), count)
for i, v := range value {
if v == nil {
return nil, false
}
switch v := v.(type) {
case func(MediaPlayer, int, string):
listeners[i] = v
case func(int, string):
2022-07-19 18:22:19 +03:00
listeners[i] = func(_ MediaPlayer, code int, message string) {
2021-09-07 17:36:50 +03:00
v(code, message)
}
case func(MediaPlayer):
2022-07-19 18:22:19 +03:00
listeners[i] = func(player MediaPlayer, _ int, _ string) {
2021-09-07 17:36:50 +03:00
v(player)
}
case func():
2022-07-19 18:22:19 +03:00
listeners[i] = func(MediaPlayer, int, string) {
2021-09-07 17:36:50 +03:00
v()
}
default:
return nil, false
}
}
return listeners, true
}
return nil, false
}
func playerEvents() []struct{ tag, cssTag string } {
return []struct{ tag, cssTag string }{
{AbortEvent, "onabort"},
{CanPlayEvent, "oncanplay"},
{CanPlayThroughEvent, "oncanplaythrough"},
{CompleteEvent, "oncomplete"},
{EmptiedEvent, "onemptied"},
{EndedEvent, "ended"},
{LoadedDataEvent, "onloadeddata"},
{LoadedMetadataEvent, "onloadedmetadata"},
{LoadStartEvent, "onloadstart"},
{PauseEvent, "onpause"},
{PlayEvent, "onplay"},
{PlayingEvent, "onplaying"},
{ProgressEvent, "onprogress"},
{SeekedEvent, "onseeked"},
{SeekingEvent, "onseeking"},
{StalledEvent, "onstalled"},
{SuspendEvent, "onsuspend"},
{WaitingEvent, "onwaiting"},
}
}
func (player *mediaPlayerData) propertyChanged(tag string) {
if player.created {
switch tag {
case Controls, Loop:
2022-10-30 17:22:33 +03:00
value, _ := boolProperty(player, tag, player.session)
if value {
2022-10-31 16:07:59 +03:00
player.session.updateProperty(player.htmlID(), tag, value)
} else {
2022-10-30 17:22:33 +03:00
player.session.removeProperty(player.htmlID(), tag)
}
case Muted:
2022-10-30 17:22:33 +03:00
value, _ := boolProperty(player, tag, player.session)
2022-11-02 20:10:19 +03:00
player.session.callFunc("setMediaMuted", player.htmlID(), value)
case Preload:
2022-10-30 17:22:33 +03:00
value, _ := enumProperty(player, tag, player.session, 0)
values := enumProperties[Preload].values
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), tag, values[value])
case AbortEvent, CanPlayEvent, CanPlayThroughEvent, CompleteEvent, EmptiedEvent,
EndedEvent, LoadedDataEvent, LoadedMetadataEvent, PauseEvent, PlayEvent, PlayingEvent, ProgressEvent,
LoadStartEvent, SeekedEvent, SeekingEvent, StalledEvent, SuspendEvent, WaitingEvent:
for _, event := range playerEvents() {
if event.tag == tag {
if value := player.getRaw(event.tag); value != nil {
switch value := value.(type) {
case []func(MediaPlayer):
if len(value) > 0 {
fn := fmt.Sprintf(`playerEvent(this, "%s")`, event.tag)
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), event.cssTag, fn)
return
}
2021-09-07 17:36:50 +03:00
}
}
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), tag, "")
break
2021-09-07 17:36:50 +03:00
}
}
case TimeUpdateEvent:
if value := player.getRaw(tag); value != nil {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "ontimeupdate", "playerTimeUpdatedEvent(this)")
} else {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "ontimeupdate", "")
2021-09-07 17:36:50 +03:00
}
case VolumeChangedEvent:
if value := player.getRaw(tag); value != nil {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "onvolumechange", "playerVolumeChangedEvent(this)")
} else {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "onvolumechange", "")
}
2021-09-07 17:36:50 +03:00
case DurationChangedEvent:
if value := player.getRaw(tag); value != nil {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "ondurationchange", "playerDurationChangedEvent(this)")
} else {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "ondurationchange", "")
}
2021-09-07 17:36:50 +03:00
case RateChangedEvent:
if value := player.getRaw(tag); value != nil {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "onratechange", "playerRateChangedEvent(this)")
} else {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "onratechange", "")
}
2021-09-07 17:36:50 +03:00
case PlayerErrorEvent:
if value := player.getRaw(tag); value != nil {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "onerror", "playerErrorEvent(this)")
} else {
2022-10-30 17:22:33 +03:00
player.session.updateProperty(player.htmlID(), "onerror", "")
}
2021-09-07 17:36:50 +03:00
case Source:
2022-10-30 17:22:33 +03:00
updateInnerHTML(player.htmlID(), player.session)
2021-09-07 17:36:50 +03:00
}
}
}
func (player *mediaPlayerData) htmlSubviews(self View, buffer *strings.Builder) {
if value := player.getRaw(Source); value != nil {
if sources, ok := value.([]MediaSource); ok && len(sources) > 0 {
2022-10-30 17:22:33 +03:00
session := player.session
2021-09-07 17:36:50 +03:00
for _, src := range sources {
if url, ok := session.resolveConstants(src.Url); ok && url != "" {
buffer.WriteString(`<source src="`)
buffer.WriteString(url)
buffer.WriteRune('"')
if mime, ok := session.resolveConstants(src.MimeType); ok && mime != "" {
buffer.WriteString(` type="`)
buffer.WriteString(mime)
buffer.WriteRune('"')
}
buffer.WriteRune('>')
}
}
}
}
}
func (player *mediaPlayerData) htmlProperties(self View, buffer *strings.Builder) {
player.viewData.htmlProperties(self, buffer)
for _, tag := range []string{Controls, Loop, Muted, Preload} {
2022-10-30 17:22:33 +03:00
if value, _ := boolProperty(player, tag, player.session); value {
2021-09-07 17:36:50 +03:00
buffer.WriteRune(' ')
buffer.WriteString(tag)
}
}
2022-10-30 17:22:33 +03:00
if value, ok := enumProperty(player, Preload, player.session, 0); ok {
2021-09-07 17:36:50 +03:00
values := enumProperties[Preload].values
buffer.WriteString(` preload="`)
buffer.WriteString(values[value])
buffer.WriteRune('"')
}
for _, event := range playerEvents() {
if value := player.getRaw(event.tag); value != nil {
switch value := value.(type) {
case []func(MediaPlayer):
if len(value) > 0 {
buffer.WriteString(` `)
buffer.WriteString(event.cssTag)
2022-10-29 20:48:03 +03:00
buffer.WriteString(`="playerEvent(this, '`)
2021-09-07 17:36:50 +03:00
buffer.WriteString(event.tag)
2022-10-29 20:48:03 +03:00
buffer.WriteString(`')"`)
2021-09-07 17:36:50 +03:00
}
}
}
}
if value := player.getRaw(TimeUpdateEvent); value != nil {
buffer.WriteString(` ontimeupdate="playerTimeUpdatedEvent(this)"`)
}
if value := player.getRaw(VolumeChangedEvent); value != nil {
buffer.WriteString(` onvolumechange="playerVolumeChangedEvent(this)"`)
}
if value := player.getRaw(DurationChangedEvent); value != nil {
buffer.WriteString(` ondurationchange="playerDurationChangedEvent(this)"`)
}
if value := player.getRaw(RateChangedEvent); value != nil {
buffer.WriteString(` onratechange="playerRateChangedEvent(this)"`)
}
if value := player.getRaw(PlayerErrorEvent); value != nil {
buffer.WriteString(` onerror="playerErrorEvent(this)"`)
}
}
func (player *mediaPlayerData) handleCommand(self View, command string, data DataObject) bool {
switch command {
case AbortEvent, CanPlayEvent, CanPlayThroughEvent, CompleteEvent, LoadStartEvent,
EmptiedEvent, EndedEvent, LoadedDataEvent, LoadedMetadataEvent, PauseEvent, PlayEvent,
PlayingEvent, ProgressEvent, SeekedEvent, SeekingEvent, StalledEvent, SuspendEvent,
WaitingEvent:
if value := player.getRaw(command); value != nil {
if listeners, ok := value.([]func(MediaPlayer)); ok {
for _, listener := range listeners {
listener(player)
}
}
}
case TimeUpdateEvent, DurationChangedEvent, RateChangedEvent, VolumeChangedEvent:
if value := player.getRaw(command); value != nil {
if listeners, ok := value.([]func(MediaPlayer, float64)); ok {
time := dataFloatProperty(data, "value")
for _, listener := range listeners {
listener(player, time)
}
}
}
case PlayerErrorEvent:
if value := player.getRaw(command); value != nil {
if listeners, ok := value.([]func(MediaPlayer, int, string)); ok {
2021-11-04 14:59:25 +03:00
code, _ := dataIntProperty(data, "code")
2021-09-07 17:36:50 +03:00
message, _ := data.PropertyValue("message")
for _, listener := range listeners {
listener(player, code, message)
}
}
}
}
return player.viewData.handleCommand(self, command, data)
}
func (player *mediaPlayerData) Play() {
2022-11-02 20:10:19 +03:00
player.session.callFunc("mediaPlay", player.htmlID())
2021-09-07 17:36:50 +03:00
}
func (player *mediaPlayerData) Pause() {
2022-11-02 20:10:19 +03:00
player.session.callFunc("mediaPause", player.htmlID())
2021-09-07 17:36:50 +03:00
}
func (player *mediaPlayerData) SetCurrentTime(seconds float64) {
2022-11-02 20:10:19 +03:00
player.session.callFunc("mediaSetSetCurrentTime", player.htmlID(), seconds)
2021-09-07 17:36:50 +03:00
}
func (player *mediaPlayerData) getFloatPlayerProperty(tag string) (float64, bool) {
2022-10-30 17:22:33 +03:00
value := player.session.htmlPropertyValue(player.htmlID(), tag)
if value != "" {
result, err := strconv.ParseFloat(value, 32)
if err == nil {
return result, true
2021-09-07 17:36:50 +03:00
}
ErrorLog(err.Error())
2021-09-07 17:36:50 +03:00
}
2021-09-07 17:36:50 +03:00
return 0, false
}
func (player *mediaPlayerData) CurrentTime() float64 {
if result, ok := player.getFloatPlayerProperty("currentTime"); ok {
return result
}
return 0
}
func (player *mediaPlayerData) Duration() float64 {
if result, ok := player.getFloatPlayerProperty("duration"); ok {
return result
}
return 0
}
func (player *mediaPlayerData) SetPlaybackRate(rate float64) {
2022-11-02 20:10:19 +03:00
player.session.callFunc("mediaSetPlaybackRate", player.htmlID(), rate)
2021-09-07 17:36:50 +03:00
}
func (player *mediaPlayerData) PlaybackRate() float64 {
if result, ok := player.getFloatPlayerProperty("playbackRate"); ok {
return result
}
return 1
}
func (player *mediaPlayerData) SetVolume(volume float64) {
if volume >= 0 && volume <= 1 {
2022-11-02 20:10:19 +03:00
player.session.callFunc("mediaSetVolume", player.htmlID(), volume)
2021-09-07 17:36:50 +03:00
}
}
func (player *mediaPlayerData) Volume() float64 {
if result, ok := player.getFloatPlayerProperty("volume"); ok {
return result
}
return 1
}
func (player *mediaPlayerData) getBoolPlayerProperty(tag string) (bool, bool) {
2022-10-30 17:22:33 +03:00
switch value := player.session.htmlPropertyValue(player.htmlID(), tag); strings.ToLower(value) {
case "0", "false", "off":
return false, true
2021-09-07 17:36:50 +03:00
case "1", "true", "on":
return false, true
2021-09-07 17:36:50 +03:00
}
2021-09-07 17:36:50 +03:00
return false, false
}
func (player *mediaPlayerData) IsEnded() bool {
if result, ok := player.getBoolPlayerProperty("ended"); ok {
return result
}
return false
}
func (player *mediaPlayerData) IsPaused() bool {
if result, ok := player.getBoolPlayerProperty("paused"); ok {
return result
}
return false
}
// MediaPlayerPlay attempts to begin playback of the media.
func MediaPlayerPlay(view View, playerID string) {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
player.Play()
} else {
ErrorLog(`The found View is not MediaPlayer`)
}
}
// MediaPlayerPause will pause playback of the media, if the media is already in a paused state this method will have no effect.
func MediaPlayerPause(view View, playerID string) {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
player.Pause()
} else {
ErrorLog(`The found View is not MediaPlayer`)
}
}
// SetMediaPlayerCurrentTime sets the current playback time in seconds.
func SetMediaPlayerCurrentTime(view View, playerID string, seconds float64) {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
player.SetCurrentTime(seconds)
} else {
ErrorLog(`The found View is not MediaPlayer`)
}
}
// MediaPlayerCurrentTime returns the current playback time in seconds.
func MediaPlayerCurrentTime(view View, playerID string) float64 {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
return player.CurrentTime()
}
ErrorLog(`The found View is not MediaPlayer`)
return 0
}
// MediaPlayerDuration returns the value indicating the total duration of the media in seconds.
// If no media data is available, the returned value is NaN.
func MediaPlayerDuration(view View, playerID string) float64 {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
return player.Duration()
}
ErrorLog(`The found View is not MediaPlayer`)
return math.NaN()
}
// SetVolume sets the audio volume, from 0.0 (silent) to 1.0 (loudest).
func SetMediaPlayerVolume(view View, playerID string, volume float64) {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
player.SetVolume(volume)
} else {
ErrorLog(`The found View is not MediaPlayer`)
}
}
// Volume returns the audio volume, from 0.0 (silent) to 1.0 (loudest).
func MediaPlayerVolume(view View, playerID string) float64 {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
return player.Volume()
}
ErrorLog(`The found View is not MediaPlayer`)
return 1
}
// SetMediaPlayerPlaybackRate sets the rate at which the media is being played back. This is used to implement user controls
// for fast forward, slow motion, and so forth. The normal playback rate is multiplied by this value to obtain
// the current rate, so a value of 1.0 indicates normal speed.
func SetMediaPlayerPlaybackRate(view View, playerID string, rate float64) {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
player.SetPlaybackRate(rate)
} else {
ErrorLog(`The found View is not MediaPlayer`)
}
}
// MediaPlayerPlaybackRate returns the rate at which the media is being played back.
func MediaPlayerPlaybackRate(view View, playerID string) float64 {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
return player.PlaybackRate()
}
ErrorLog(`The found View is not MediaPlayer`)
return 1
}
// IsMediaPlayerEnded function tells whether the media element is ended.
func IsMediaPlayerEnded(view View, playerID string) bool {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
return player.IsEnded()
}
ErrorLog(`The found View is not MediaPlayer`)
return false
}
// IsMediaPlayerPaused function tells whether the media element is paused.
func IsMediaPlayerPaused(view View, playerID string) bool {
if playerID != "" {
view = ViewByID(view, playerID)
}
if player, ok := view.(MediaPlayer); ok {
return player.IsPaused()
}
ErrorLog(`The found View is not MediaPlayer`)
return false
}