From 1bc99e9d89acdd31bdfd2fc07dec5a04fcd0bccf Mon Sep 17 00:00:00 2001 From: Yaroslav Popov Date: Tue, 13 Nov 2018 15:14:58 +0300 Subject: [PATCH] Added HTTP headers setting to video_player plugin --- .../videoplayer/VideoPlayerPlugin.java | 12 ++++++++- .../ios/Classes/VideoPlayerPlugin.m | 27 ++++++++++++------- packages/video_player/lib/video_player.dart | 10 ++++--- .../video_player/test/video_player_test.dart | 2 ++ 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/packages/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java index de4f44cdb567..276aafad75f3 100644 --- a/packages/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java +++ b/packages/video_player/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java @@ -73,6 +73,7 @@ private static class VideoPlayer { EventChannel eventChannel, TextureRegistry.SurfaceTextureEntry textureEntry, String dataSource, + Map httpHeaders, Result result) { this.eventChannel = eventChannel; this.textureEntry = textureEntry; @@ -86,13 +87,18 @@ private static class VideoPlayer { if (uri.getScheme().equals("asset") || uri.getScheme().equals("file")) { dataSourceFactory = new DefaultDataSourceFactory(context, "ExoPlayer"); } else { - dataSourceFactory = + DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory( "ExoPlayer", null, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true); + + dataSourceFactory = httpDataSourceFactory; + if (httpHeaders != null) { + httpDataSourceFactory.getDefaultRequestProperties().set(httpHeaders); + } } MediaSource mediaSource = buildMediaSource(uri, dataSourceFactory, context); @@ -328,15 +334,19 @@ public void onMethodCall(MethodCall call, Result result) { eventChannel, handle, "asset:///" + assetLookupKey, + null, result); videoPlayers.put(handle.id(), player); } else { + @SuppressWarnings("unchecked") + Map httpHeaders = call.argument("httpHeaders"); player = new VideoPlayer( registrar.context(), eventChannel, handle, (String) call.argument("uri"), + httpHeaders, result); videoPlayers.put(handle.id(), player); } diff --git a/packages/video_player/ios/Classes/VideoPlayerPlugin.m b/packages/video_player/ios/Classes/VideoPlayerPlugin.m index 16110a5e4e47..69f200888d72 100644 --- a/packages/video_player/ios/Classes/VideoPlayerPlugin.m +++ b/packages/video_player/ios/Classes/VideoPlayerPlugin.m @@ -38,7 +38,9 @@ @interface FLTVideoPlayer : NSObject @property(nonatomic, readonly) bool isPlaying; @property(nonatomic, readonly) bool isLooping; @property(nonatomic, readonly) bool isInitialized; -- (instancetype)initWithURL:(NSURL*)url frameUpdater:(FLTFrameUpdater*)frameUpdater; +- (instancetype)initWithURL:(NSURL*)url + frameUpdater:(FLTFrameUpdater*)frameUpdater + httpHeaders:(NSDictionary*)headers; - (void)play; - (void)pause; - (void)setIsLooping:(bool)isLooping; @@ -54,7 +56,7 @@ - (void)updatePlayingState; @implementation FLTVideoPlayer - (instancetype)initWithAsset:(NSString*)asset frameUpdater:(FLTFrameUpdater*)frameUpdater { NSString* path = [[NSBundle mainBundle] pathForResource:asset ofType:nil]; - return [self initWithURL:[NSURL fileURLWithPath:path] frameUpdater:frameUpdater]; + return [self initWithURL:[NSURL fileURLWithPath:path] frameUpdater:frameUpdater httpHeaders:nil]; } - (void)addObservers:(AVPlayerItem*)item { @@ -140,8 +142,15 @@ - (void)createVideoOutputAndDisplayLink:(FLTFrameUpdater*)frameUpdater { _displayLink.paused = YES; } -- (instancetype)initWithURL:(NSURL*)url frameUpdater:(FLTFrameUpdater*)frameUpdater { - AVPlayerItem* item = [AVPlayerItem playerItemWithURL:url]; +- (instancetype)initWithURL:(NSURL*)url + frameUpdater:(FLTFrameUpdater*)frameUpdater + httpHeaders:(NSDictionary*)headers { + NSDictionary* options = nil; + if (headers != (NSDictionary*)[NSNull null]) { + options = @{@"AVURLAssetHTTPHeaderFieldsKey" : headers}; + } + AVURLAsset* urlAsset = [AVURLAsset URLAssetWithURL:url options:options]; + AVPlayerItem* item = [AVPlayerItem playerItemWithAsset:urlAsset]; return [self initWithPlayerItem:item frameUpdater:frameUpdater]; } @@ -153,7 +162,7 @@ - (CGAffineTransform)fixTransform:(AVAssetTrack*)videoTrack { // displays the video https://github.com/flutter/flutter/issues/17606#issuecomment-413473181 if (transform.tx == 0 && transform.ty == 0) { NSInteger rotationDegrees = (NSInteger)round(radiansToDegrees(atan2(transform.b, transform.a))); - NSLog(@"TX and TY are 0. Rotation: %d. Natural width,height: %f, %f", rotationDegrees, + NSLog(@"TX and TY are 0. Rotation: %ld. Natural width,height: %f, %f", (long)rotationDegrees, videoTrack.naturalSize.width, videoTrack.naturalSize.height); if (rotationDegrees == 90) { NSLog(@"Setting transform tx"); @@ -185,8 +194,6 @@ - (instancetype)initWithPlayerItem:(AVPlayerItem*)item frameUpdater:(FLTFrameUpd if (_disposed) return; if ([videoTrack statusOfValueForKey:@"preferredTransform" error:nil] == AVKeyValueStatusLoaded) { - CGSize size = videoTrack.naturalSize; - // Rotate the video by using a videoComposition and the preferredTransform _preferredTransform = [self fixTransform:videoTrack]; // Note: @@ -209,8 +216,6 @@ - (instancetype)initWithPlayerItem:(AVPlayerItem*)item frameUpdater:(FLTFrameUpd _player = [AVPlayer playerWithPlayerItem:item]; _player.actionAtItemEnd = AVPlayerActionAtItemEndNone; - CGSize size = item.presentationSize; - [self createVideoOutputAndDisplayLink:frameUpdater]; [self addObservers:item]; @@ -462,8 +467,10 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { player = [[FLTVideoPlayer alloc] initWithAsset:assetPath frameUpdater:frameUpdater]; [self onPlayerSetup:player frameUpdater:frameUpdater result:result]; } else if (uriArg) { + NSDictionary* httpHeaders = argsMap[@"httpHeaders"]; player = [[FLTVideoPlayer alloc] initWithURL:[NSURL URLWithString:uriArg] - frameUpdater:frameUpdater]; + frameUpdater:frameUpdater + httpHeaders:httpHeaders]; [self onPlayerSetup:player frameUpdater:frameUpdater result:result]; } else { result(FlutterMethodNotImplemented); diff --git a/packages/video_player/lib/video_player.dart b/packages/video_player/lib/video_player.dart index 441057de32b6..72aa13ddc341 100644 --- a/packages/video_player/lib/video_player.dart +++ b/packages/video_player/lib/video_player.dart @@ -157,8 +157,8 @@ class VideoPlayerController extends ValueNotifier { /// the network. /// /// The URI for the video is given by the [dataSource] argument and must not be - /// null. - VideoPlayerController.network(this.dataSource) + /// null. The [httpHeaders] for the request to the [dataSource] is optional and may be null. + VideoPlayerController.network(this.dataSource, {this.httpHeaders}) : dataSourceType = DataSourceType.network, package = null, super(VideoPlayerValue(duration: null)); @@ -175,6 +175,7 @@ class VideoPlayerController extends ValueNotifier { int _textureId; final String dataSource; + Map httpHeaders; /// Describes the type of data source this [VideoPlayerController] /// is constructed with. @@ -203,7 +204,10 @@ class VideoPlayerController extends ValueNotifier { }; break; case DataSourceType.network: - dataSourceDescription = {'uri': dataSource}; + dataSourceDescription = { + 'uri': dataSource, + 'httpHeaders': httpHeaders + }; break; case DataSourceType.file: dataSourceDescription = {'uri': dataSource}; diff --git a/packages/video_player/test/video_player_test.dart b/packages/video_player/test/video_player_test.dart index 94bebbd331d8..23b11a7aa204 100644 --- a/packages/video_player/test/video_player_test.dart +++ b/packages/video_player/test/video_player_test.dart @@ -23,6 +23,8 @@ class FakeController extends ValueNotifier @override String get package => null; @override + Map httpHeaders; + @override Future get position async => value.position; @override