2021-09-07 17:36:50 +03:00
package rui
import (
"fmt"
"math"
"strconv"
"strings"
)
2024-09-12 14:05:11 +03:00
// Constants which related to media player properties and events
2021-09-07 17:36:50 +03:00
const (
2024-09-18 13:50:06 +03:00
// 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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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"
2024-09-18 13:50:06 +03:00
// 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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
2024-09-18 13:50:06 +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
)
2024-09-12 14:05:11 +03:00
// 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
}
2024-09-12 14:05:11 +03:00
// MediaSource represent one media file source
2021-09-07 17:36:50 +03:00
type MediaSource struct {
2024-09-12 14:05:11 +03:00
// Url of the source
Url string
// MimeType of the source
2021-09-07 17:36:50 +03:00
MimeType string
}
2022-09-01 11:04:50 +03:00
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 {
2024-05-02 15:07:57 +03:00
return getViewString ( player , nil )
2022-05-22 12:54:02 +03:00
}
2022-01-15 01:20:04 +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 ) {
2021-11-20 11:15:28 +03:00
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 )
2021-11-20 11:15:28 +03:00
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 )
2021-11-20 11:15:28 +03:00
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 )
2021-11-20 11:15:28 +03:00
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 )
2021-11-20 11:15:28 +03:00
player . propertyChangedEvent ( tag )
2021-09-07 17:36:50 +03:00
return true
}
default :
2021-11-20 11:15:28 +03:00
return player . viewData . set ( tag , value )
2021-09-07 17:36:50 +03:00
}
2021-11-20 11:15:28 +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 ) {
2021-11-20 11:15:28 +03:00
if player . created {
switch tag {
case Controls , Loop :
2022-10-30 17:22:33 +03:00
value , _ := boolProperty ( player , tag , player . session )
2021-11-20 11:15:28 +03:00
if value {
2022-10-31 16:07:59 +03:00
player . session . updateProperty ( player . htmlID ( ) , tag , value )
2021-11-20 11:15:28 +03:00
} else {
2022-10-30 17:22:33 +03:00
player . session . removeProperty ( player . htmlID ( ) , tag )
2021-11-20 11:15:28 +03:00
}
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 )
2021-11-20 11:15:28 +03:00
case Preload :
2022-10-30 17:22:33 +03:00
value , _ := enumProperty ( player , tag , player . session , 0 )
2021-11-20 11:15:28 +03:00
values := enumProperties [ Preload ] . values
2022-10-30 17:22:33 +03:00
player . session . updateProperty ( player . htmlID ( ) , tag , values [ value ] )
2021-11-20 11:15:28 +03:00
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 )
2021-11-20 11:15:28 +03:00
return
}
2021-09-07 17:36:50 +03:00
}
}
2022-10-30 17:22:33 +03:00
player . session . updateProperty ( player . htmlID ( ) , tag , "" )
2021-11-20 11:15:28 +03:00
break
2021-09-07 17:36:50 +03:00
}
2021-11-20 11:15:28 +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)" )
2021-11-20 11:15:28 +03:00
} else {
2022-10-30 17:22:33 +03:00
player . session . updateProperty ( player . htmlID ( ) , "ontimeupdate" , "" )
2021-09-07 17:36:50 +03:00
}
2021-11-20 11:15:28 +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)" )
2021-11-20 11:15:28 +03:00
} else {
2022-10-30 17:22:33 +03:00
player . session . updateProperty ( player . htmlID ( ) , "onvolumechange" , "" )
2021-11-20 11:15:28 +03:00
}
2021-09-07 17:36:50 +03:00
2021-11-20 11:15:28 +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)" )
2021-11-20 11:15:28 +03:00
} else {
2022-10-30 17:22:33 +03:00
player . session . updateProperty ( player . htmlID ( ) , "ondurationchange" , "" )
2021-11-20 11:15:28 +03:00
}
2021-09-07 17:36:50 +03:00
2021-11-20 11:15:28 +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)" )
2021-11-20 11:15:28 +03:00
} else {
2022-10-30 17:22:33 +03:00
player . session . updateProperty ( player . htmlID ( ) , "onratechange" , "" )
2021-11-20 11:15:28 +03:00
}
2021-09-07 17:36:50 +03:00
2021-11-20 11:15:28 +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)" )
2021-11-20 11:15:28 +03:00
} else {
2022-10-30 17:22:33 +03:00
player . session . updateProperty ( player . htmlID ( ) , "onerror" , "" )
2021-11-20 11:15:28 +03:00
}
2021-09-07 17:36:50 +03:00
2021-11-20 11:15:28 +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 )
2022-10-30 12:35:22 +03:00
if value != "" {
result , err := strconv . ParseFloat ( value , 32 )
if err == nil {
return result , true
2021-09-07 17:36:50 +03:00
}
2022-10-30 12:35:22 +03:00
ErrorLog ( err . Error ( ) )
2021-09-07 17:36:50 +03:00
}
2022-10-30 12:35:22 +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 ) {
2022-10-30 12:35:22 +03:00
case "0" , "false" , "off" :
return false , true
2021-09-07 17:36:50 +03:00
2022-10-30 12:35:22 +03:00
case "1" , "true" , "on" :
return false , true
2021-09-07 17:36:50 +03:00
}
2022-10-30 12:35:22 +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
}