Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
[video_player] Add macOS support
Browse files Browse the repository at this point in the history
  • Loading branch information
cbenhagen committed Mar 13, 2021
1 parent f7096d7 commit f7e7e03
Show file tree
Hide file tree
Showing 33 changed files with 2,508 additions and 75 deletions.
4 changes: 4 additions & 0 deletions packages/video_player/video_player/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.0.3

* Add macOS support.

## 2.0.2

* Fix `VideoPlayerValue` size and aspect ratio documentation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ void main() {
VideoPlayerController _controller;
tearDown(() async => _controller.dispose());

group('asset videos', () {
group('network videos', () {
setUp(() {
_controller = VideoPlayerController.asset('assets/Butterfly-209.mp4');
_controller = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
);
});

testWidgets('can be initialized', (WidgetTester tester) async {
Expand All @@ -32,81 +34,30 @@ void main() {
expect(_controller.value.position, const Duration(seconds: 0));
expect(_controller.value.isPlaying, false);
expect(_controller.value.duration,
const Duration(seconds: 7, milliseconds: 540));
const Duration(seconds: 4, milliseconds: 036));
});

testWidgets(
'reports buffering status',
(WidgetTester tester) async {
VideoPlayerController networkController = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
);
await networkController.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await networkController.setVolume(0);
final Completer<void> started = Completer();
final Completer<void> ended = Completer();
bool startedBuffering = false;
bool endedBuffering = false;
networkController.addListener(() {
if (networkController.value.isBuffering && !startedBuffering) {
startedBuffering = true;
started.complete();
}
if (startedBuffering &&
!networkController.value.isBuffering &&
!endedBuffering) {
endedBuffering = true;
ended.complete();
}
});

await networkController.play();
await networkController.seekTo(const Duration(seconds: 5));
await tester.pumpAndSettle(_playDuration);
await networkController.pause();

expect(networkController.value.isPlaying, false);
expect(networkController.value.position,
(Duration position) => position > const Duration(seconds: 0));

await started;
expect(startedBuffering, true);
testWidgets('can be played', (WidgetTester tester) async {
await _controller.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await _controller.setVolume(0);

await ended;
expect(endedBuffering, true);
},
skip: !(kIsWeb || defaultTargetPlatform == TargetPlatform.android),
);
await _controller.play();
await tester.pumpAndSettle(_playDuration);

testWidgets(
'can be played',
(WidgetTester tester) async {
await _controller.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await _controller.setVolume(0);

await _controller.play();
await tester.pumpAndSettle(_playDuration);

expect(_controller.value.isPlaying, true);
expect(_controller.value.position,
(Duration position) => position > const Duration(seconds: 0));
},
);
expect(_controller.value.isPlaying, true);
expect(_controller.value.position,
(Duration position) => position > const Duration(seconds: 0));
});

testWidgets(
'can seek',
(WidgetTester tester) async {
await _controller.initialize();
testWidgets('can seek', (WidgetTester tester) async {
await _controller.initialize();

await _controller.seekTo(const Duration(seconds: 3));
await _controller.seekTo(const Duration(seconds: 3));

expect(_controller.value.position, const Duration(seconds: 3));
},
);
expect(_controller.value.position, const Duration(seconds: 3));
});

testWidgets(
'can be paused',
Expand All @@ -129,8 +80,136 @@ void main() {
},
);

testWidgets('test video player view with local asset',
(WidgetTester tester) async {
testWidgets('reports buffering status', (WidgetTester tester) async {
await _controller.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await _controller.setVolume(0);
final Completer<void> started = Completer();
final Completer<void> ended = Completer();
bool startedBuffering = false;
bool endedBuffering = false;
_controller.addListener(
() {
if (_controller.value.isBuffering && !startedBuffering) {
startedBuffering = true;
started.complete();
}
if (startedBuffering &&
!_controller.value.isBuffering &&
!endedBuffering) {
endedBuffering = true;
ended.complete();
}
},
);

await _controller.play();
await _controller.seekTo(const Duration(seconds: 5));
await tester.pumpAndSettle(_playDuration);
await _controller.pause();

expect(_controller.value.isPlaying, false);
expect(_controller.value.position,
(Duration position) => position > const Duration(seconds: 0));

await started;
expect(startedBuffering, true);

await ended;
expect(endedBuffering, true);
});

testWidgets('can show video player', (WidgetTester tester) async {
Future<bool> started() async {
await _controller.initialize();
await _controller.play();
return true;
}

await tester.pumpWidget(Material(
elevation: 0,
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: FutureBuilder<bool>(
future: started(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (snapshot.data == true) {
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
} else {
return const Text('waiting for video to load');
}
},
),
),
),
));

await tester.pumpAndSettle(_playDuration);
expect(_controller.value.isPlaying, true);
});
});

group('asset videos', () {
setUp(() {
_controller = VideoPlayerController.asset('assets/Butterfly-209.mp4');
});

testWidgets('can be initialized', (WidgetTester tester) async {
await _controller.initialize();

expect(_controller.value.isInitialized, true);
expect(_controller.value.position, const Duration(seconds: 0));
expect(_controller.value.isPlaying, false);
expect(_controller.value.duration,
const Duration(seconds: 7, milliseconds: 540));
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));

testWidgets('can be played', (WidgetTester tester) async {
await _controller.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await _controller.setVolume(0);

await _controller.play();
await tester.pumpAndSettle(_playDuration);

expect(_controller.value.isPlaying, true);
expect(_controller.value.position,
(Duration position) => position > const Duration(seconds: 0));
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));

testWidgets('can seek', (WidgetTester tester) async {
await _controller.initialize();

await _controller.seekTo(const Duration(seconds: 3));

expect(_controller.value.position, const Duration(seconds: 3));
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));

testWidgets('can be paused', (WidgetTester tester) async {
await _controller.initialize();
// Mute to allow playing without DOM interaction on Web.
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
await _controller.setVolume(0);

// Play for a second, then pause, and then wait a second.
await _controller.play();
await tester.pumpAndSettle(_playDuration);
await _controller.pause();
final Duration pausedPosition = _controller.value.position;
await tester.pumpAndSettle(_playDuration);

// Verify that we stopped playing after the pause.
expect(_controller.value.isPlaying, false);
expect(_controller.value.position, pausedPosition);
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));

testWidgets('can show video player', (WidgetTester tester) async {
Future<bool> started() async {
await _controller.initialize();
await _controller.play();
Expand Down Expand Up @@ -159,8 +238,8 @@ void main() {
),
));

await tester.pumpAndSettle();
await tester.pumpAndSettle(_playDuration);
expect(_controller.value.isPlaying, true);
}, skip: kIsWeb); // Web does not support local assets.
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));
});
}
6 changes: 6 additions & 0 deletions packages/video_player/video_player/example/macos/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Flutter-related
**/Flutter/ephemeral/
**/Pods/

# Xcode-related
**/xcuserdata/
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
Loading

0 comments on commit f7e7e03

Please sign in to comment.