Professional Documents
Culture Documents
Video Player Web - Dart
Video Player Web - Dart
Video Player Web - Dart
import 'dart:html';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:video_player_platform_interface/video_player_platform_interface.
dart';
int _textureCounter = 1;
@override
Future<void> init() async {
return _disposeAllPlayers();
}
@override
Future<void> dispose(int textureId) async {
_videoPlayers[textureId].dispose();
_videoPlayers.remove(textureId);
return null;
}
void _disposeAllPlayers() {
_videoPlayers.values
.forEach((_VideoPlayer videoPlayer) => videoPlayer.dispose());
_videoPlayers.clear();
}
@override
Future<int> create(DataSource dataSource) async {
final int textureId = _textureCounter;
_textureCounter++;
String uri;
switch (dataSource.sourceType) {
case DataSourceType.network:
// Do NOT modify the incoming uri, it can be a Blob, and Safari doesn't
// like blobs that have changed.
uri = dataSource.uri;
break;
case DataSourceType.asset:
String assetUrl = dataSource.asset;
if (dataSource.package != null && dataSource.package.isNotEmpty) {
assetUrl = 'packages/${dataSource.package}/$assetUrl';
}
// 'webOnlyAssetManager' is only in the web version of dart:ui
// ignore: undefined_prefixed_name
assetUrl = ui.webOnlyAssetManager.getAssetUrl(assetUrl);
uri = assetUrl;
break;
case DataSourceType.file:
return Future.error(UnimplementedError(
'web implementation of video_player cannot play local files'));
}
player.initialize();
_videoPlayers[textureId] = player;
return textureId;
}
@override
Future<void> setLooping(int textureId, bool looping) async {
return _videoPlayers[textureId].setLooping(looping);
}
@override
Future<void> play(int textureId) async {
return _videoPlayers[textureId].play();
}
@override
Future<void> pause(int textureId) async {
return _videoPlayers[textureId].pause();
}
@override
Future<void> setVolume(int textureId, double volume) async {
return _videoPlayers[textureId].setVolume(volume);
}
@override
Future<void> seekTo(int textureId, Duration position) async {
return _videoPlayers[textureId].seekTo(position);
}
@override
Future<Duration> getPosition(int textureId) async {
_videoPlayers[textureId].sendBufferingUpdate();
return _videoPlayers[textureId].getPosition();
}
@override
Stream<VideoEvent> videoEventsFor(int textureId) {
return _videoPlayers[textureId].eventController.stream;
}
@override
Widget buildView(int textureId) {
return HtmlElementView(viewType: 'videoPlayer-$textureId');
}
}
class _VideoPlayer {
_VideoPlayer({this.uri, this.textureId});
void initialize() {
videoElement = VideoElement()
..src = uri
..autoplay = false
..controls = false
..style.border = 'none';
videoElement.onCanPlay.listen((dynamic _) {
if (!isInitialized) {
isInitialized = true;
sendInitialized();
}
});
// The error event fires when some form of error occurs while attempting to
load or perform the media.
videoElement.onError.listen((Event _) {
// The Event itself (_) doesn't contain info about the actual error.
// We need to look at the HTMLMediaElement.error.
// See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
error
MediaError error = videoElement.error;
eventController.addError(PlatformException(
code: _kErrorValueToErrorName[error.code],
message: error.message != '' ? error.message : _kDefaultErrorMessage,
details: _kErrorValueToErrorDescription[error.code],
));
});
videoElement.onEnded.listen((dynamic _) {
eventController.add(VideoEvent(eventType: VideoEventType.completed));
});
}
void sendBufferingUpdate() {
eventController.add(VideoEvent(
buffered: _toDurationRange(videoElement.buffered),
eventType: VideoEventType.bufferingUpdate,
));
}
Future<void> play() {
return videoElement.play().catchError((e) {
// play() attempts to begin playback of the media. It returns
// a Promise which can get rejected in case of failure to begin
// playback for any reason, such as permission issues.
// The rejection handler is called with a DomException.
// See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/
play
DomException exception = e;
eventController.addError(PlatformException(
code: exception.name,
message: exception.message,
));
}, test: (e) => e is DomException);
}
void pause() {
videoElement.pause();
}
Duration getPosition() {
return Duration(milliseconds: (videoElement.currentTime * 1000).round());
}
void sendInitialized() {
eventController.add(
VideoEvent(
eventType: VideoEventType.initialized,
duration: Duration(
milliseconds: (videoElement.duration * 1000).round(),
),
size: Size(
videoElement.videoWidth.toDouble() ?? 0.0,
videoElement.videoHeight.toDouble() ?? 0.0,
),
),
);
}
void dispose() {
videoElement.removeAttribute('src');
videoElement.load();
}