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

Commit f7e7e03

Browse files
committed
[video_player] Add macOS support
1 parent f7096d7 commit f7e7e03

33 files changed

+2508
-75
lines changed

packages/video_player/video_player/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.0.3
2+
3+
* Add macOS support.
4+
15
## 2.0.2
26

37
* Fix `VideoPlayerValue` size and aspect ratio documentation

packages/video_player/video_player/example/integration_test/video_player_test.dart

+153-74
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ void main() {
2020
VideoPlayerController _controller;
2121
tearDown(() async => _controller.dispose());
2222

23-
group('asset videos', () {
23+
group('network videos', () {
2424
setUp(() {
25-
_controller = VideoPlayerController.asset('assets/Butterfly-209.mp4');
25+
_controller = VideoPlayerController.network(
26+
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
27+
);
2628
});
2729

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

38-
testWidgets(
39-
'reports buffering status',
40-
(WidgetTester tester) async {
41-
VideoPlayerController networkController = VideoPlayerController.network(
42-
'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4',
43-
);
44-
await networkController.initialize();
45-
// Mute to allow playing without DOM interaction on Web.
46-
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
47-
await networkController.setVolume(0);
48-
final Completer<void> started = Completer();
49-
final Completer<void> ended = Completer();
50-
bool startedBuffering = false;
51-
bool endedBuffering = false;
52-
networkController.addListener(() {
53-
if (networkController.value.isBuffering && !startedBuffering) {
54-
startedBuffering = true;
55-
started.complete();
56-
}
57-
if (startedBuffering &&
58-
!networkController.value.isBuffering &&
59-
!endedBuffering) {
60-
endedBuffering = true;
61-
ended.complete();
62-
}
63-
});
64-
65-
await networkController.play();
66-
await networkController.seekTo(const Duration(seconds: 5));
67-
await tester.pumpAndSettle(_playDuration);
68-
await networkController.pause();
69-
70-
expect(networkController.value.isPlaying, false);
71-
expect(networkController.value.position,
72-
(Duration position) => position > const Duration(seconds: 0));
73-
74-
await started;
75-
expect(startedBuffering, true);
40+
testWidgets('can be played', (WidgetTester tester) async {
41+
await _controller.initialize();
42+
// Mute to allow playing without DOM interaction on Web.
43+
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
44+
await _controller.setVolume(0);
7645

77-
await ended;
78-
expect(endedBuffering, true);
79-
},
80-
skip: !(kIsWeb || defaultTargetPlatform == TargetPlatform.android),
81-
);
46+
await _controller.play();
47+
await tester.pumpAndSettle(_playDuration);
8248

83-
testWidgets(
84-
'can be played',
85-
(WidgetTester tester) async {
86-
await _controller.initialize();
87-
// Mute to allow playing without DOM interaction on Web.
88-
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
89-
await _controller.setVolume(0);
90-
91-
await _controller.play();
92-
await tester.pumpAndSettle(_playDuration);
93-
94-
expect(_controller.value.isPlaying, true);
95-
expect(_controller.value.position,
96-
(Duration position) => position > const Duration(seconds: 0));
97-
},
98-
);
49+
expect(_controller.value.isPlaying, true);
50+
expect(_controller.value.position,
51+
(Duration position) => position > const Duration(seconds: 0));
52+
});
9953

100-
testWidgets(
101-
'can seek',
102-
(WidgetTester tester) async {
103-
await _controller.initialize();
54+
testWidgets('can seek', (WidgetTester tester) async {
55+
await _controller.initialize();
10456

105-
await _controller.seekTo(const Duration(seconds: 3));
57+
await _controller.seekTo(const Duration(seconds: 3));
10658

107-
expect(_controller.value.position, const Duration(seconds: 3));
108-
},
109-
);
59+
expect(_controller.value.position, const Duration(seconds: 3));
60+
});
11061

11162
testWidgets(
11263
'can be paused',
@@ -129,8 +80,136 @@ void main() {
12980
},
13081
);
13182

132-
testWidgets('test video player view with local asset',
133-
(WidgetTester tester) async {
83+
testWidgets('reports buffering status', (WidgetTester tester) async {
84+
await _controller.initialize();
85+
// Mute to allow playing without DOM interaction on Web.
86+
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
87+
await _controller.setVolume(0);
88+
final Completer<void> started = Completer();
89+
final Completer<void> ended = Completer();
90+
bool startedBuffering = false;
91+
bool endedBuffering = false;
92+
_controller.addListener(
93+
() {
94+
if (_controller.value.isBuffering && !startedBuffering) {
95+
startedBuffering = true;
96+
started.complete();
97+
}
98+
if (startedBuffering &&
99+
!_controller.value.isBuffering &&
100+
!endedBuffering) {
101+
endedBuffering = true;
102+
ended.complete();
103+
}
104+
},
105+
);
106+
107+
await _controller.play();
108+
await _controller.seekTo(const Duration(seconds: 5));
109+
await tester.pumpAndSettle(_playDuration);
110+
await _controller.pause();
111+
112+
expect(_controller.value.isPlaying, false);
113+
expect(_controller.value.position,
114+
(Duration position) => position > const Duration(seconds: 0));
115+
116+
await started;
117+
expect(startedBuffering, true);
118+
119+
await ended;
120+
expect(endedBuffering, true);
121+
});
122+
123+
testWidgets('can show video player', (WidgetTester tester) async {
124+
Future<bool> started() async {
125+
await _controller.initialize();
126+
await _controller.play();
127+
return true;
128+
}
129+
130+
await tester.pumpWidget(Material(
131+
elevation: 0,
132+
child: Directionality(
133+
textDirection: TextDirection.ltr,
134+
child: Center(
135+
child: FutureBuilder<bool>(
136+
future: started(),
137+
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
138+
if (snapshot.data == true) {
139+
return AspectRatio(
140+
aspectRatio: _controller.value.aspectRatio,
141+
child: VideoPlayer(_controller),
142+
);
143+
} else {
144+
return const Text('waiting for video to load');
145+
}
146+
},
147+
),
148+
),
149+
),
150+
));
151+
152+
await tester.pumpAndSettle(_playDuration);
153+
expect(_controller.value.isPlaying, true);
154+
});
155+
});
156+
157+
group('asset videos', () {
158+
setUp(() {
159+
_controller = VideoPlayerController.asset('assets/Butterfly-209.mp4');
160+
});
161+
162+
testWidgets('can be initialized', (WidgetTester tester) async {
163+
await _controller.initialize();
164+
165+
expect(_controller.value.isInitialized, true);
166+
expect(_controller.value.position, const Duration(seconds: 0));
167+
expect(_controller.value.isPlaying, false);
168+
expect(_controller.value.duration,
169+
const Duration(seconds: 7, milliseconds: 540));
170+
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));
171+
172+
testWidgets('can be played', (WidgetTester tester) async {
173+
await _controller.initialize();
174+
// Mute to allow playing without DOM interaction on Web.
175+
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
176+
await _controller.setVolume(0);
177+
178+
await _controller.play();
179+
await tester.pumpAndSettle(_playDuration);
180+
181+
expect(_controller.value.isPlaying, true);
182+
expect(_controller.value.position,
183+
(Duration position) => position > const Duration(seconds: 0));
184+
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));
185+
186+
testWidgets('can seek', (WidgetTester tester) async {
187+
await _controller.initialize();
188+
189+
await _controller.seekTo(const Duration(seconds: 3));
190+
191+
expect(_controller.value.position, const Duration(seconds: 3));
192+
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));
193+
194+
testWidgets('can be paused', (WidgetTester tester) async {
195+
await _controller.initialize();
196+
// Mute to allow playing without DOM interaction on Web.
197+
// See https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
198+
await _controller.setVolume(0);
199+
200+
// Play for a second, then pause, and then wait a second.
201+
await _controller.play();
202+
await tester.pumpAndSettle(_playDuration);
203+
await _controller.pause();
204+
final Duration pausedPosition = _controller.value.position;
205+
await tester.pumpAndSettle(_playDuration);
206+
207+
// Verify that we stopped playing after the pause.
208+
expect(_controller.value.isPlaying, false);
209+
expect(_controller.value.position, pausedPosition);
210+
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));
211+
212+
testWidgets('can show video player', (WidgetTester tester) async {
134213
Future<bool> started() async {
135214
await _controller.initialize();
136215
await _controller.play();
@@ -159,8 +238,8 @@ void main() {
159238
),
160239
));
161240

162-
await tester.pumpAndSettle();
241+
await tester.pumpAndSettle(_playDuration);
163242
expect(_controller.value.isPlaying, true);
164-
}, skip: kIsWeb); // Web does not support local assets.
243+
}, skip: (kIsWeb || defaultTargetPlatform == TargetPlatform.macOS));
165244
});
166245
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Flutter-related
2+
**/Flutter/ephemeral/
3+
**/Pods/
4+
5+
# Xcode-related
6+
**/xcuserdata/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2+
#include "ephemeral/Flutter-Generated.xcconfig"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2+
#include "ephemeral/Flutter-Generated.xcconfig"

0 commit comments

Comments
 (0)