Skip to content

Commit

Permalink
feat: video_player web options
Browse files Browse the repository at this point in the history
  • Loading branch information
defuncart committed Mar 3, 2023
1 parent 2f21321 commit 9351e64
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 1 deletion.
12 changes: 11 additions & 1 deletion packages/video_player/video_player/lib/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import 'package:video_player_platform_interface/video_player_platform_interface.
import 'src/closed_caption_file.dart';

export 'package:video_player_platform_interface/video_player_platform_interface.dart'
show DurationRange, DataSourceType, VideoFormat, VideoPlayerOptions;
show
DurationRange,
DataSourceType,
VideoFormat,
VideoPlayerOptions,
VideoPlayerWebOptions;

export 'src/closed_caption_file.dart';

Expand Down Expand Up @@ -364,6 +369,11 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
_creatingCompleter!.complete(null);
final Completer<void> initializingCompleter = Completer<void>();

if (videoPlayerOptions?.webOptions != null) {
await _videoPlayerPlatform.setWebOptions(
_textureId, videoPlayerOptions!.webOptions!);
}

void eventListener(VideoEvent event) {
if (_isDisposed) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ abstract class VideoPlayerPlatform extends PlatformInterface {
Future<void> setMixWithOthers(bool mixWithOthers) {
throw UnimplementedError('setMixWithOthers() has not been implemented.');
}

/// Sets additional options on web
Future<void> setWebOptions(int textureId, VideoPlayerWebOptions controls) {
throw UnimplementedError('setWebOptions() has not been implemented.');
}
}

class _PlaceholderImplementation extends VideoPlayerPlatform {}
Expand Down Expand Up @@ -359,6 +364,7 @@ class VideoPlayerOptions {
VideoPlayerOptions({
this.mixWithOthers = false,
this.allowBackgroundPlayback = false,
this.webOptions,
});

/// Set this to true to keep playing video in background, when app goes in background.
Expand All @@ -371,4 +377,41 @@ class VideoPlayerOptions {
/// Note: This option will be silently ignored in the web platform (there is
/// currently no way to implement this feature in this platform).
final bool mixWithOthers;

/// Additional web controls
final VideoPlayerWebOptions? webOptions;
}

/// [VideoPlayerWebOptions] can be optionally used to set additional web settings
@immutable
class VideoPlayerWebOptions {
/// [VideoPlayerWebOptions] can be optionally used to set additional web settings
const VideoPlayerWebOptions({
this.controlsEnabled = false,
this.allowDownload = true,
this.allowFullscreen = true,
this.allowPlaybackRate = true,
this.allowContextMenu = true,
});

/// Whether native controls are enabled
final bool controlsEnabled;

/// Whether downloaded control is displayed
///
/// Only applicable when [controlsEnabled] is true
final bool allowDownload;

/// Whether fullscreen control is enabled
///
/// Only applicable when [controlsEnabled] is true
final bool allowFullscreen;

/// Whether playback rate control is displayed
///
/// Only applicable when [controlsEnabled] is true
final bool allowPlaybackRate;

/// Whether context menu (right click) is allowed
final bool allowContextMenu;
}
32 changes: 32 additions & 0 deletions packages/video_player/video_player_web/lib/src/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class VideoPlayer {

final StreamController<VideoEvent> _eventController;
final html.VideoElement _videoElement;
dynamic Function(html.Event)? _onContextMenu;

bool _isInitialized = false;
bool _isBuffering = false;
Expand Down Expand Up @@ -188,9 +189,40 @@ class VideoPlayer {
return Duration(milliseconds: (_videoElement.currentTime * 1000).round());
}

/// Sets control options
Future<void> setControls(VideoPlayerWebOptions controls) async {
if (controls.controlsEnabled) {
_videoElement.controls = true;
final List<String> attributes = <String>[];
if (!controls.allowDownload) {
attributes.add('nodownload');
}
if (!controls.allowFullscreen) {
attributes.add('nofullscreen');
}
if (!controls.allowPlaybackRate) {
attributes.add('noplaybackrate');
}
if (attributes.isNotEmpty) {
_videoElement.setAttribute(
'controlsList',
attributes
.reduce((String value, String element) => '$value $element'),
);
}
}

if (!controls.allowContextMenu) {
_onContextMenu = (html.Event event) => event.preventDefault();
_videoElement.addEventListener('contextmenu', _onContextMenu);
}
}

/// Disposes of the current [html.VideoElement].
void dispose() {
_videoElement.removeAttribute('src');
_videoElement.removeEventListener('contextmenu', _onContextMenu);
_onContextMenu = null;
_videoElement.load();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ class VideoPlayerPlugin extends VideoPlayerPlatform {
return _player(textureId).events;
}

@override
Future<void> setWebOptions(int textureId, VideoPlayerWebOptions controls) {
return _player(textureId).setControls(controls);
}

// Retrieves a [VideoPlayer] by its internal `id`.
// It must have been created earlier from the [create] method.
VideoPlayer _player(int id) {
Expand Down

0 comments on commit 9351e64

Please sign in to comment.