Skip to content

Commit 88ca9e2

Browse files
Revert "[video_player] Passing http headers to file constructor (flutter#3266)" (flutter#3424)
This reverts commit 73e7ef7.
1 parent 73e7ef7 commit 88ca9e2

File tree

10 files changed

+35
-151
lines changed

10 files changed

+35
-151
lines changed

packages/video_player/video_player/CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
## 2.6.0
1+
## NEXT
22

3-
* Adds option to configure HTTP headers via `VideoPlayerController` to fix access to M3U8 files on Android.
43
* Aligns Dart and Flutter SDK constraints.
54

65
## 2.5.3

packages/video_player/video_player/lib/video_player.dart

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
230230
/// null.
231231
/// **Android only**: The [formatHint] option allows the caller to override
232232
/// the video format detection code.
233-
/// [httpHeaders] option allows to specify HTTP headers.
233+
/// [httpHeaders] option allows to specify HTTP headers
234234
/// for the request to the [dataSource].
235235
VideoPlayerController.network(
236236
this.dataSource, {
@@ -246,16 +246,14 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
246246
/// Constructs a [VideoPlayerController] playing a video from a file.
247247
///
248248
/// This will load the file from a file:// URI constructed from [file]'s path.
249-
/// [httpHeaders] option allows to specify HTTP headers, mainly used for hls files like (m3u8).
250249
VideoPlayerController.file(File file,
251-
{Future<ClosedCaptionFile>? closedCaptionFile,
252-
this.videoPlayerOptions,
253-
this.httpHeaders = const <String, String>{}})
250+
{Future<ClosedCaptionFile>? closedCaptionFile, this.videoPlayerOptions})
254251
: _closedCaptionFileFuture = closedCaptionFile,
255252
dataSource = Uri.file(file.absolute.path).toString(),
256253
dataSourceType = DataSourceType.file,
257254
package = null,
258255
formatHint = null,
256+
httpHeaders = const <String, String>{},
259257
super(VideoPlayerValue(duration: Duration.zero));
260258

261259
/// Constructs a [VideoPlayerController] playing a video from a contentUri.
@@ -346,7 +344,6 @@ class VideoPlayerController extends ValueNotifier<VideoPlayerValue> {
346344
dataSourceDescription = DataSource(
347345
sourceType: DataSourceType.file,
348346
uri: dataSource,
349-
httpHeaders: httpHeaders,
350347
);
351348
break;
352349
case DataSourceType.contentUri:

packages/video_player/video_player/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Flutter plugin for displaying inline video with other Flutter
33
widgets on Android, iOS, and web.
44
repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player
55
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
6-
version: 2.6.0
6+
version: 2.5.3
77

88
environment:
99
sdk: ">=2.17.0 <3.0.0"

packages/video_player/video_player/test/video_player_test.dart

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -358,22 +358,6 @@ void main() {
358358
reason: 'Actual string: $uri');
359359
}, skip: kIsWeb /* Web does not support file assets. */);
360360

361-
test('file with headers (m3u8)', () async {
362-
final VideoPlayerController controller = VideoPlayerController.file(
363-
File('a.avi'),
364-
httpHeaders: <String, String>{'Authorization': 'Bearer token'},
365-
);
366-
await controller.initialize();
367-
368-
final String uri = fakeVideoPlayerPlatform.dataSources[0].uri!;
369-
expect(uri.startsWith('file:///'), true, reason: 'Actual string: $uri');
370-
expect(uri.endsWith('/a.avi'), true, reason: 'Actual string: $uri');
371-
372-
expect(
373-
fakeVideoPlayerPlatform.dataSources[0].httpHeaders,
374-
<String, String>{'Authorization': 'Bearer token'},
375-
);
376-
}, skip: kIsWeb /* Web does not support file assets. */);
377361
test('successful initialize on controller with error clears error',
378362
() async {
379363
final VideoPlayerController controller = VideoPlayerController.network(

packages/video_player/video_player_android/CHANGELOG.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
## 2.4.0
2-
3-
* Allows setting the ExoPlayer user agent by passing a User-Agent HTTP header.
4-
51
## 2.3.12
62

73
* Clarifies explanation of endorsement in README.

packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,10 @@ final class VideoPlayer {
5656

5757
private final EventChannel eventChannel;
5858

59-
private static final String USER_AGENT = "User-Agent";
60-
6159
@VisibleForTesting boolean isInitialized = false;
6260

6361
private final VideoPlayerOptions options;
6462

65-
private DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory();
66-
6763
VideoPlayer(
6864
Context context,
6965
EventChannel eventChannel,
@@ -77,11 +73,23 @@ final class VideoPlayer {
7773
this.options = options;
7874

7975
ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build();
76+
8077
Uri uri = Uri.parse(dataSource);
78+
DataSource.Factory dataSourceFactory;
8179

82-
buildHttpDataSourceFactory(httpHeaders);
83-
DataSource.Factory dataSourceFactory =
84-
new DefaultDataSource.Factory(context, httpDataSourceFactory);
80+
if (isHTTP(uri)) {
81+
DefaultHttpDataSource.Factory httpDataSourceFactory =
82+
new DefaultHttpDataSource.Factory()
83+
.setUserAgent("ExoPlayer")
84+
.setAllowCrossProtocolRedirects(true);
85+
86+
if (httpHeaders != null && !httpHeaders.isEmpty()) {
87+
httpDataSourceFactory.setDefaultRequestProperties(httpHeaders);
88+
}
89+
dataSourceFactory = httpDataSourceFactory;
90+
} else {
91+
dataSourceFactory = new DefaultDataSource.Factory(context);
92+
}
8593

8694
MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, formatHint, context);
8795

@@ -98,29 +106,20 @@ final class VideoPlayer {
98106
EventChannel eventChannel,
99107
TextureRegistry.SurfaceTextureEntry textureEntry,
100108
VideoPlayerOptions options,
101-
QueuingEventSink eventSink,
102-
DefaultHttpDataSource.Factory httpDataSourceFactory) {
109+
QueuingEventSink eventSink) {
103110
this.eventChannel = eventChannel;
104111
this.textureEntry = textureEntry;
105112
this.options = options;
106-
this.httpDataSourceFactory = httpDataSourceFactory;
107113

108114
setUpVideoPlayer(exoPlayer, eventSink);
109115
}
110116

111-
@VisibleForTesting
112-
public void buildHttpDataSourceFactory(@NonNull Map<String, String> httpHeaders) {
113-
final boolean httpHeadersNotEmpty = !httpHeaders.isEmpty();
114-
final String userAgent =
115-
httpHeadersNotEmpty && httpHeaders.containsKey(USER_AGENT)
116-
? httpHeaders.get(USER_AGENT)
117-
: "ExoPlayer";
118-
119-
httpDataSourceFactory.setUserAgent(userAgent).setAllowCrossProtocolRedirects(true);
120-
121-
if (httpHeadersNotEmpty) {
122-
httpDataSourceFactory.setDefaultRequestProperties(httpHeaders);
117+
private static boolean isHTTP(Uri uri) {
118+
if (uri == null || uri.getScheme() == null) {
119+
return false;
123120
}
121+
String scheme = uri.getScheme();
122+
return scheme.equals("http") || scheme.equals("https");
124123
}
125124

126125
private MediaSource buildMediaSource(
@@ -150,11 +149,13 @@ private MediaSource buildMediaSource(
150149
switch (type) {
151150
case C.CONTENT_TYPE_SS:
152151
return new SsMediaSource.Factory(
153-
new DefaultSsChunkSource.Factory(mediaDataSourceFactory), mediaDataSourceFactory)
152+
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
153+
new DefaultDataSource.Factory(context, mediaDataSourceFactory))
154154
.createMediaSource(MediaItem.fromUri(uri));
155155
case C.CONTENT_TYPE_DASH:
156156
return new DashMediaSource.Factory(
157-
new DefaultDashChunkSource.Factory(mediaDataSourceFactory), mediaDataSourceFactory)
157+
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
158+
new DefaultDataSource.Factory(context, mediaDataSourceFactory))
158159
.createMediaSource(MediaItem.fromUri(uri));
159160
case C.CONTENT_TYPE_HLS:
160161
return new HlsMediaSource.Factory(mediaDataSourceFactory)

packages/video_player/video_player_android/android/src/test/java/io/flutter/plugins/videoplayer/VideoPlayerTest.java

Lines changed: 4 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,15 @@
55
package io.flutter.plugins.videoplayer;
66

77
import static org.junit.Assert.assertEquals;
8-
import static org.mockito.Mockito.any;
98
import static org.mockito.Mockito.mock;
10-
import static org.mockito.Mockito.never;
11-
import static org.mockito.Mockito.spy;
129
import static org.mockito.Mockito.verify;
1310
import static org.mockito.Mockito.when;
1411

1512
import com.google.android.exoplayer2.ExoPlayer;
1613
import com.google.android.exoplayer2.Format;
17-
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
1814
import io.flutter.plugin.common.EventChannel;
1915
import io.flutter.view.TextureRegistry;
2016
import java.util.HashMap;
21-
import java.util.Map;
2217
import org.junit.Before;
2318
import org.junit.Test;
2419
import org.junit.runner.RunWith;
@@ -34,7 +29,6 @@ public class VideoPlayerTest {
3429
private TextureRegistry.SurfaceTextureEntry fakeSurfaceTextureEntry;
3530
private VideoPlayerOptions fakeVideoPlayerOptions;
3631
private QueuingEventSink fakeEventSink;
37-
private DefaultHttpDataSource.Factory httpDataSourceFactorySpy;
3832

3933
@Captor private ArgumentCaptor<HashMap<String, Object>> eventCaptor;
4034

@@ -47,76 +41,6 @@ public void before() {
4741
fakeSurfaceTextureEntry = mock(TextureRegistry.SurfaceTextureEntry.class);
4842
fakeVideoPlayerOptions = mock(VideoPlayerOptions.class);
4943
fakeEventSink = mock(QueuingEventSink.class);
50-
httpDataSourceFactorySpy = spy(new DefaultHttpDataSource.Factory());
51-
}
52-
53-
@Test
54-
public void videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNull() {
55-
VideoPlayer videoPlayer =
56-
new VideoPlayer(
57-
fakeExoPlayer,
58-
fakeEventChannel,
59-
fakeSurfaceTextureEntry,
60-
fakeVideoPlayerOptions,
61-
fakeEventSink,
62-
httpDataSourceFactorySpy);
63-
64-
videoPlayer.buildHttpDataSourceFactory(new HashMap<>());
65-
66-
verify(httpDataSourceFactorySpy).setUserAgent("ExoPlayer");
67-
verify(httpDataSourceFactorySpy).setAllowCrossProtocolRedirects(true);
68-
verify(httpDataSourceFactorySpy, never()).setDefaultRequestProperties(any());
69-
}
70-
71-
@Test
72-
public void
73-
videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNonNullAndUserAgentSpecified() {
74-
VideoPlayer videoPlayer =
75-
new VideoPlayer(
76-
fakeExoPlayer,
77-
fakeEventChannel,
78-
fakeSurfaceTextureEntry,
79-
fakeVideoPlayerOptions,
80-
fakeEventSink,
81-
httpDataSourceFactorySpy);
82-
Map<String, String> httpHeaders =
83-
new HashMap<String, String>() {
84-
{
85-
put("header", "value");
86-
put("User-Agent", "userAgent");
87-
}
88-
};
89-
90-
videoPlayer.buildHttpDataSourceFactory(httpHeaders);
91-
92-
verify(httpDataSourceFactorySpy).setUserAgent("userAgent");
93-
verify(httpDataSourceFactorySpy).setAllowCrossProtocolRedirects(true);
94-
verify(httpDataSourceFactorySpy).setDefaultRequestProperties(httpHeaders);
95-
}
96-
97-
@Test
98-
public void
99-
videoPlayer_buildsHttpDataSourceFactoryProperlyWhenHttpHeadersNonNullAndUserAgentNotSpecified() {
100-
VideoPlayer videoPlayer =
101-
new VideoPlayer(
102-
fakeExoPlayer,
103-
fakeEventChannel,
104-
fakeSurfaceTextureEntry,
105-
fakeVideoPlayerOptions,
106-
fakeEventSink,
107-
httpDataSourceFactorySpy);
108-
Map<String, String> httpHeaders =
109-
new HashMap<String, String>() {
110-
{
111-
put("header", "value");
112-
}
113-
};
114-
115-
videoPlayer.buildHttpDataSourceFactory(httpHeaders);
116-
117-
verify(httpDataSourceFactorySpy).setUserAgent("ExoPlayer");
118-
verify(httpDataSourceFactorySpy).setAllowCrossProtocolRedirects(true);
119-
verify(httpDataSourceFactorySpy).setDefaultRequestProperties(httpHeaders);
12044
}
12145

12246
@Test
@@ -127,8 +51,7 @@ public void sendInitializedSendsExpectedEvent_90RotationDegrees() {
12751
fakeEventChannel,
12852
fakeSurfaceTextureEntry,
12953
fakeVideoPlayerOptions,
130-
fakeEventSink,
131-
httpDataSourceFactorySpy);
54+
fakeEventSink);
13255
Format testFormat =
13356
new Format.Builder().setWidth(100).setHeight(200).setRotationDegrees(90).build();
13457

@@ -156,8 +79,7 @@ public void sendInitializedSendsExpectedEvent_270RotationDegrees() {
15679
fakeEventChannel,
15780
fakeSurfaceTextureEntry,
15881
fakeVideoPlayerOptions,
159-
fakeEventSink,
160-
httpDataSourceFactorySpy);
82+
fakeEventSink);
16183
Format testFormat =
16284
new Format.Builder().setWidth(100).setHeight(200).setRotationDegrees(270).build();
16385

@@ -185,8 +107,7 @@ public void sendInitializedSendsExpectedEvent_0RotationDegrees() {
185107
fakeEventChannel,
186108
fakeSurfaceTextureEntry,
187109
fakeVideoPlayerOptions,
188-
fakeEventSink,
189-
httpDataSourceFactorySpy);
110+
fakeEventSink);
190111
Format testFormat =
191112
new Format.Builder().setWidth(100).setHeight(200).setRotationDegrees(0).build();
192113

@@ -214,8 +135,7 @@ public void sendInitializedSendsExpectedEvent_180RotationDegrees() {
214135
fakeEventChannel,
215136
fakeSurfaceTextureEntry,
216137
fakeVideoPlayerOptions,
217-
fakeEventSink,
218-
httpDataSourceFactorySpy);
138+
fakeEventSink);
219139
Format testFormat =
220140
new Format.Builder().setWidth(100).setHeight(200).setRotationDegrees(180).build();
221141

packages/video_player/video_player_android/lib/src/android_video_player.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ class AndroidVideoPlayer extends VideoPlayerPlatform {
4949
break;
5050
case DataSourceType.file:
5151
uri = dataSource.uri;
52-
httpHeaders = dataSource.httpHeaders;
5352
break;
5453
case DataSourceType.contentUri:
5554
uri = dataSource.uri;

packages/video_player/video_player_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: video_player_android
22
description: Android implementation of the video_player plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
5-
version: 2.4.0
5+
version: 2.3.12
66

77
environment:
88
sdk: ">=2.17.0 <3.0.0"

packages/video_player/video_player_android/test/android_video_player_test.dart

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,6 @@ void main() {
176176
expect(textureId, 3);
177177
});
178178

179-
test('create with file (some headers)', () async {
180-
final int? textureId = await player.create(DataSource(
181-
sourceType: DataSourceType.file,
182-
uri: 'someUri',
183-
httpHeaders: <String, String>{'Authorization': 'Bearer token'},
184-
));
185-
expect(log.log.last, 'create');
186-
expect(log.createMessage?.uri, 'someUri');
187-
expect(log.createMessage?.httpHeaders,
188-
<String, String>{'Authorization': 'Bearer token'});
189-
expect(textureId, 3);
190-
});
191179
test('setLooping', () async {
192180
await player.setLooping(1, true);
193181
expect(log.log.last, 'setLooping');

0 commit comments

Comments
 (0)