Skip to content

Commit

Permalink
Ios multiple instance (solid-software#26)
Browse files Browse the repository at this point in the history
* Supporting multiple players.

* Support multiple instance of the player on iOS

* Added new VC to second Player to the example
  • Loading branch information
kraigspear authored Feb 18, 2020
1 parent ee644cb commit a0e3567
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 73 deletions.
17 changes: 16 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ class _MyAppState extends State<MyApp> {
GlobalKey imageKey;
VlcPlayer videoView;
VlcPlayerController _videoViewController;
VlcPlayerController _videoViewController2;

@override
void initState() {
imageKey = new GlobalKey();
_videoViewController = new VlcPlayerController();
_videoViewController2 = new VlcPlayerController();
super.initState();
}

Expand Down Expand Up @@ -50,6 +52,19 @@ class _MyAppState extends State<MyApp> {
),
),
),
new VlcPlayer(
defaultWidth: 640,
defaultHeight: 360,
url: "http://213.226.254.135:91/mjpg/video.mjpg",
controller: _videoViewController2,
placeholder: Container(
height: 250.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[CircularProgressIndicator()],
),
),
),
Expanded(
child: image == null
? Container()
Expand All @@ -69,4 +84,4 @@ class _MyAppState extends State<MyApp> {
image = file;
});
}
}
}
18 changes: 16 additions & 2 deletions ios/Classes/FlutterVlcPlayerPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,23 @@
@end

@interface FLTPlayerView : NSObject<FlutterPlatformView>
+(instancetype) initWithView : (UIView *)view;

/// View to show video over
@property (nonatomic, strong) UIView *hostedView;
/// Player showing video
@property (nonatomic, strong) VLCMediaPlayer *player;
/// result to comunicate back to Flutter
@property (nonatomic) FlutterResult result;
/// Set to indicate that aspect has been set which is only needed once.
@property (nonatomic, assign) BOOL aspectSet;


/// Initialize a new instance with the channel
/// @param channel Comuniate back to flutter
+ (instancetype)initWithChannel: (FlutterMethodChannel*) channel;

@end

@interface FLTPlayerViewFactory : NSObject<FlutterPlatformViewFactory>
+ (instancetype)initWithRegistrar : (NSObject<FlutterPluginRegistrar>*)registrar : (UIView *) view;
+ (instancetype)initWithRegistrar : (NSObject<FlutterPluginRegistrar>*)registrar;
@end
149 changes: 79 additions & 70 deletions ios/Classes/FlutterVlcPlayerPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,110 +9,119 @@
#import "VLCMediaPlayer.h"

@implementation FLTPlayerView
UIView *_videoView;

NSObject<FlutterBinaryMessenger> *_messenger;

+ (instancetype)initWithView:(UIView *)view{
if (_videoView == nil){
_videoView = view;
}
return [[super alloc] init];
+ (instancetype)initWithChannel: (FlutterMethodChannel*) channel
{
FLTPlayerView *instance = [[super alloc] init];

UIView *hostedView = [[UIView alloc] init];

hostedView.contentMode = UIViewContentModeScaleAspectFit;
hostedView.backgroundColor = [UIColor whiteColor];
hostedView.clipsToBounds = YES;
hostedView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

instance.hostedView = hostedView;

[channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {

instance.result = result;

if([call.method isEqualToString:@"playVideo"])
{
NSString *url = call.arguments[@"url"];

VLCMediaPlayer *player = [[VLCMediaPlayer alloc] init];

instance.player = player;

VLCMedia *media = [VLCMedia mediaWithURL:[NSURL URLWithString:url]];
player.media = media;
player.position = 0.5;
player.drawable = instance.hostedView;
[player addObserver:instance forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];

[player play];
} else if ([call.method isEqualToString:@"dispose"])
{
[instance.player stop];
} else if ([call.method isEqualToString:@"getSnapshot"])
{
UIView *drawable = instance.player.drawable;
CGSize size = drawable.frame.size;

UIGraphicsBeginImageContextWithOptions(size, false, 0.0);

CGRect rec = drawable.frame;
[drawable drawViewHierarchyInRect:rec afterScreenUpdates:false];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

NSString *byteArray = [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

result(@{@"snapshot" : byteArray});
}

}];

return instance;
}

- (nonnull UIView *)view {
return _videoView;
return self.hostedView;
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

// Player won't play if this aspect does't get set in response to the KV changing.

if (self.aspectSet) return;
if (!self.player.isPlaying) return;

[_player setDrawable:_hostedView];
[_player setVideoAspectRatio:"0.7"];
[_player setCurrentVideoTrackIndex:0];
[_player setScaleFactor:0.0];
NSString *aspectStr = [NSString stringWithUTF8String:[_player videoAspectRatio]];
self.result(@{@"aspectRatio" : aspectStr});
self.aspectSet = YES;
}


@end


@implementation FLTPlayerViewFactory
NSObject<FlutterPluginRegistrar> *_registrar;
UIView *_view;

+ (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar : (UIView*) view{
+ (instancetype)initWithRegistrar : (NSObject<FlutterPluginRegistrar>*)registrar {
_registrar = registrar;
_view = view;
return [[super alloc] init];
}

- (nonnull NSObject<FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(NSObject<FlutterBinaryMessenger> *)messenger {
NSString *_methodCallName = [NSString stringWithFormat:@"%@_%@",@"flutter_video_plugin/getVideoView", [NSString stringWithFormat:@"%lld", viewId]];
FlutterMethodChannel* _channel = [FlutterMethodChannel
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:_methodCallName
binaryMessenger:[_registrar messenger]];
[_registrar addMethodCallDelegate:[[FlutterVlcPlayerPlugin alloc] init] channel:_channel];
return [FLTPlayerView initWithView: _view];


return [FLTPlayerView initWithChannel:channel];
}


@end


@implementation FlutterVlcPlayerPlugin
VLCMediaPlayer *_player;
FlutterResult _result;
UIView *_view;

+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar {
CGRect _rect = CGRectMake(0, 0, 700, 100);
_view = [[UIView alloc] initWithFrame: _rect];
_view.contentMode = UIViewContentModeScaleAspectFit;
_view.backgroundColor = [UIColor whiteColor];
_view.clipsToBounds = YES;
_view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[registrar registerViewFactory: [FLTPlayerViewFactory initWithRegistrar: registrar : _view] withId:@"flutter_video_plugin/getVideoView"];
}

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result{
_result = result;
NSString* _methodName = call.method;
if ([_methodName isEqualToString:@"playVideo"]){
NSString *_url = call.arguments[@"url"];
_player = [[VLCMediaPlayer alloc] init];
VLCMedia *_media = [VLCMedia mediaWithURL:[NSURL URLWithString:_url]];
[_player setMedia:_media];
[_player setPosition:0.5];

[_player setDrawable: _videoView];
[_player addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
[_player play];
} else if ([_methodName isEqualToString:@"dispose"]){
[_player stop];
}else if ([_methodName isEqualToString:@"getSnapshot"]){
UIView *_drawable = _player.drawable;
CGSize _size = _drawable.frame.size;

UIGraphicsBeginImageContextWithOptions(_size, false, 0.0);

CGRect rec = _drawable.frame;
[_drawable drawViewHierarchyInRect:rec afterScreenUpdates:false];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

NSString *_byteArray = [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

result(@{@"snapshot" : _byteArray});
}
[registrar registerViewFactory: [FLTPlayerViewFactory initWithRegistrar: registrar] withId:@"flutter_video_plugin/getVideoView"];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

if ([_player isPlaying]){
[_player setDrawable:_view];
[_player setVideoAspectRatio:"0.7"];
[_player setCurrentVideoTrackIndex:0];
[_player setScaleFactor:0.0];
char *_aspectRatioChar = [_player videoAspectRatio];
NSNumber *_aspectRatio = [NSString stringWithFormat:@"%s", _aspectRatioChar];

_result(@{@"aspectRatio" : _aspectRatio});
// _result(nil);
}

}

@end

0 comments on commit a0e3567

Please sign in to comment.