From f4df91afa8013000cd853b90dd7e9ef3b90c01f5 Mon Sep 17 00:00:00 2001 From: Timothy Shamilov Date: Sat, 30 Jun 2018 00:11:58 -0400 Subject: [PATCH] (ios): add bg color & bg image. fix indentation. add aspectstretch option. (#138) Increment to v2.1.0 for minor change. --- README.md | 2 +- package.json | 2 +- plugin.xml | 2 +- src/ios/StreamingMedia.m | 363 ++++++++++++++++++++------------------- 4 files changed, 190 insertions(+), 179 deletions(-) diff --git a/README.md b/README.md index e386391..3c329d1 100755 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ cordova plugin add https://github.com/nchutchind/cordova-plugin-streaming-media var options = { bgColor: "#FFFFFF", bgImage: "", - bgImageScale: "fit", // other valid values: "stretch" + bgImageScale: "fit", // other valid values: "stretch", "aspectStretch" initFullscreen: false, // true is default. iOS only. keepAwake: false, // prevents device from sleeping. true is default. Android only. successCallback: function() { diff --git a/package.json b/package.json index 289f2e8..1af8859 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova-plugin-streaming-media", - "version": "2.0.0", + "version": "2.1.0", "description": "This plugin allows you to stream audio and video in a fullscreen, native player on iOS and Android.", "main": "index.js", "scripts": { diff --git a/plugin.xml b/plugin.xml index 33544b2..11d6912 100755 --- a/plugin.xml +++ b/plugin.xml @@ -3,7 +3,7 @@ xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-streaming-media" - version="2.0.0"> + version="2.1.0"> StreamingMedia diff --git a/src/ios/StreamingMedia.m b/src/ios/StreamingMedia.m index 9326473..bed42fa 100755 --- a/src/ios/StreamingMedia.m +++ b/src/ios/StreamingMedia.m @@ -6,22 +6,22 @@ #import "PortraitVideo.h" @interface StreamingMedia() - - (void)parseOptions:(NSDictionary *) options type:(NSString *) type; - - (void)play:(CDVInvokedUrlCommand *) command type:(NSString *) type; - - (void)setBackgroundColor:(NSString *)color; - - (void)setImage:(NSString*)imagePath withScaleType:(NSString*)imageScaleType; - - (UIImage*)getImage: (NSString *)imageName; - - (void)startPlayer:(NSString*)uri; - - (void)moviePlayBackDidFinish:(NSNotification*)notification; - - (void)cleanup; +- (void)parseOptions:(NSDictionary *) options type:(NSString *) type; +- (void)play:(CDVInvokedUrlCommand *) command type:(NSString *) type; +- (void)setBackgroundColor:(NSString *)color; +- (void)setImage:(NSString*)imagePath withScaleType:(NSString*)imageScaleType; +- (UIImage*)getImage: (NSString *)imageName; +- (void)startPlayer:(NSString*)uri; +- (void)moviePlayBackDidFinish:(NSNotification*)notification; +- (void)cleanup; @end @implementation StreamingMedia { - NSString* callbackId; - AVPlayerViewController *moviePlayer; - BOOL shouldAutoClose; - UIColor *backgroundColor; - UIImageView *imageView; + NSString* callbackId; + AVPlayerViewController *moviePlayer; + BOOL shouldAutoClose; + UIColor *backgroundColor; + UIImageView *imageView; BOOL initFullscreen; NSString *mOrientation; } @@ -34,50 +34,50 @@ -(void)parseOptions:(NSDictionary *)options type:(NSString *) type { // Common options mOrientation = options[@"orientation"] ?: @"default"; - if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"shouldAutoClose"]) { - shouldAutoClose = [[options objectForKey:@"shouldAutoClose"] boolValue]; - } else { - shouldAutoClose = YES; - } - if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgColor"]) { - [self setBackgroundColor:[options objectForKey:@"bgColor"]]; - } else { - backgroundColor = [UIColor blackColor]; - } - + if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"shouldAutoClose"]) { + shouldAutoClose = [[options objectForKey:@"shouldAutoClose"] boolValue]; + } else { + shouldAutoClose = YES; + } + if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgColor"]) { + [self setBackgroundColor:[options objectForKey:@"bgColor"]]; + } else { + backgroundColor = [UIColor blackColor]; + } + if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"initFullscreen"]) { initFullscreen = [[options objectForKey:@"initFullscreen"] boolValue]; } else { initFullscreen = YES; } - - if ([type isEqualToString:TYPE_AUDIO]) { - // bgImage - // bgImageScale - if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgImage"]) { - NSString *imageScale = DEFAULT_IMAGE_SCALE; - if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgImageScale"]) { - imageScale = [options objectForKey:@"bgImageScale"]; - } - [self setImage:[options objectForKey:@"bgImage"] withScaleType:imageScale]; - } - // bgColor - if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgColor"]) { - NSLog(@"Found option for bgColor"); - [self setBackgroundColor:[options objectForKey:@"bgColor"]]; - } else { - backgroundColor = [UIColor blackColor]; - } - } - // No specific options for video yet + + if ([type isEqualToString:TYPE_AUDIO]) { + // bgImage + // bgImageScale + if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgImage"]) { + NSString *imageScale = DEFAULT_IMAGE_SCALE; + if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgImageScale"]) { + imageScale = [options objectForKey:@"bgImageScale"]; + } + [self setImage:[options objectForKey:@"bgImage"] withScaleType:imageScale]; + } + // bgColor + if (![options isKindOfClass:[NSNull class]] && [options objectForKey:@"bgColor"]) { + NSLog(@"Found option for bgColor"); + [self setBackgroundColor:[options objectForKey:@"bgColor"]]; + } else { + backgroundColor = [UIColor blackColor]; + } + } + // No specific options for video yet } -(void)play:(CDVInvokedUrlCommand *) command type:(NSString *) type { - callbackId = command.callbackId; - NSString *mediaUrl = [command.arguments objectAtIndex:0]; - [self parseOptions:[command.arguments objectAtIndex:1] type:type]; - - [self startPlayer:mediaUrl]; + callbackId = command.callbackId; + NSString *mediaUrl = [command.arguments objectAtIndex:0]; + [self parseOptions:[command.arguments objectAtIndex:1] type:type]; + + [self startPlayer:mediaUrl]; } -(void)stop:(CDVInvokedUrlCommand *) command type:(NSString *) type { @@ -88,13 +88,13 @@ -(void)stop:(CDVInvokedUrlCommand *) command type:(NSString *) type { } -(void)playVideo:(CDVInvokedUrlCommand *) command { - AVAudioSession *session = [AVAudioSession sharedInstance]; - [session setCategory:AVAudioSessionCategoryPlayback error:nil]; - [self play:command type:[NSString stringWithString:TYPE_VIDEO]]; + AVAudioSession *session = [AVAudioSession sharedInstance]; + [session setCategory:AVAudioSessionCategoryPlayback error:nil]; + [self play:command type:[NSString stringWithString:TYPE_VIDEO]]; } -(void)playAudio:(CDVInvokedUrlCommand *) command { - [self play:command type:[NSString stringWithString:TYPE_AUDIO]]; + [self play:command type:[NSString stringWithString:TYPE_AUDIO]]; } -(void)stopAudio:(CDVInvokedUrlCommand *) command { @@ -102,84 +102,87 @@ -(void)stopAudio:(CDVInvokedUrlCommand *) command { } -(void) setBackgroundColor:(NSString *)color { - if ([color hasPrefix:@"#"]) { - // HEX value - unsigned rgbValue = 0; - NSScanner *scanner = [NSScanner scannerWithString:color]; - [scanner setScanLocation:1]; // bypass '#' character - [scanner scanHexInt:&rgbValue]; - backgroundColor = [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]; - } else { - // Color name - NSString *selectorString = [[color lowercaseString] stringByAppendingString:@"Color"]; - SEL selector = NSSelectorFromString(selectorString); - UIColor *colorObj = [UIColor blackColor]; - if ([UIColor respondsToSelector:selector]) { - colorObj = [UIColor performSelector:selector]; - } - backgroundColor = colorObj; - } + if ([color hasPrefix:@"#"]) { + // HEX value + unsigned rgbValue = 0; + NSScanner *scanner = [NSScanner scannerWithString:color]; + [scanner setScanLocation:1]; // bypass '#' character + [scanner scanHexInt:&rgbValue]; + backgroundColor = [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]; + } else { + // Color name + NSString *selectorString = [[color lowercaseString] stringByAppendingString:@"Color"]; + SEL selector = NSSelectorFromString(selectorString); + UIColor *colorObj = [UIColor blackColor]; + if ([UIColor respondsToSelector:selector]) { + colorObj = [UIColor performSelector:selector]; + } + backgroundColor = colorObj; + } } -(UIImage*)getImage: (NSString *)imageName { - UIImage *image = nil; - if (imageName != (id)[NSNull null]) { - if ([imageName hasPrefix:@"http"]) { - // Web image - image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageName]]]; - } else if ([imageName hasPrefix:@"www/"]) { - // Asset image - image = [UIImage imageNamed:imageName]; - } else if ([imageName hasPrefix:@"file://"]) { - // Stored image - image = [UIImage imageWithData:[NSData dataWithContentsOfFile:[[NSURL URLWithString:imageName] path]]]; - } else if ([imageName hasPrefix:@"data:"]) { - // base64 encoded string - NSURL *imageURL = [NSURL URLWithString:imageName]; - NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; - image = [UIImage imageWithData:imageData]; - } else { - // explicit path - image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imageName]]; - } - } - return image; + UIImage *image = nil; + if (imageName != (id)[NSNull null]) { + if ([imageName hasPrefix:@"http"]) { + // Web image + image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageName]]]; + } else if ([imageName hasPrefix:@"www/"]) { + // Asset image + image = [UIImage imageNamed:imageName]; + } else if ([imageName hasPrefix:@"file://"]) { + // Stored image + image = [UIImage imageWithData:[NSData dataWithContentsOfFile:[[NSURL URLWithString:imageName] path]]]; + } else if ([imageName hasPrefix:@"data:"]) { + // base64 encoded string + NSURL *imageURL = [NSURL URLWithString:imageName]; + NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; + image = [UIImage imageWithData:imageData]; + } else { + // explicit path + image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imageName]]; + } + } + return image; } - (void)orientationChanged:(NSNotification *)notification { - if (imageView != nil) { - // adjust imageView for rotation - //imageView.bounds = moviePlayer.backgroundView.bounds; - //imageView.frame = moviePlayer.backgroundView.frame; - } + if (imageView != nil) { + // adjust imageView for rotation + imageView.bounds = moviePlayer.contentOverlayView.bounds; + imageView.frame = moviePlayer.contentOverlayView.frame; + } } -(void)setImage:(NSString*)imagePath withScaleType:(NSString*)imageScaleType { - imageView = [[UIImageView alloc] initWithFrame:self.viewController.view.bounds]; - if (imageScaleType == nil) { - NSLog(@"imagescaletype was NIL"); - imageScaleType = DEFAULT_IMAGE_SCALE; - } - if ([imageScaleType isEqualToString:@"stretch"]){ - // Stretches image to fill all available background space, disregarding aspect ratio - imageView.contentMode = UIViewContentModeScaleToFill; - //moviePlayer.backgroundView.contentMode = UIViewContentModeScaleToFill; - } else if ([imageScaleType isEqualToString:@"fit"]) { - // Stretches image to fill all possible space while retaining aspect ratio - imageView.contentMode = UIViewContentModeScaleAspectFit; - //moviePlayer.backgroundView.contentMode = UIViewContentModeScaleAspectFit; - } else { - // Places image in the center of the screen - imageView.contentMode = UIViewContentModeCenter; - //moviePlayer.backgroundView.contentMode = UIViewContentModeCenter; - } - - [imageView setImage:[self getImage:imagePath]]; + imageView = [[UIImageView alloc] initWithFrame:self.viewController.view.bounds]; + if (imageScaleType == nil) { + NSLog(@"imagescaletype was NIL"); + imageScaleType = DEFAULT_IMAGE_SCALE; + } + if ([imageScaleType isEqualToString:@"stretch"]){ + // Stretches image to fill all available background space, disregarding aspect ratio + imageView.contentMode = UIViewContentModeScaleToFill; + + } else if ([imageScaleType isEqualToString:@"fit"]) { + // fits entire image perfectly + imageView.contentMode = UIViewContentModeScaleAspectFit; + } else if ([imageScaleType isEqualToString:@"aspectStretch"]) { + // Stretches image to fill all possible space while retaining aspect ratio + imageView.contentMode = UIViewContentModeScaleAspectFill; + + } else { + // Places image in the center of the screen + imageView.contentMode = UIViewContentModeCenter; + //moviePlayer.backgroundView.contentMode = UIViewContentModeCenter; + } + + [imageView setImage:[self getImage:imagePath]]; } -(void)startPlayer:(NSString*)uri { - NSURL *url = [NSURL URLWithString:uri]; + NSURL *url = [NSURL URLWithString:uri]; AVPlayer *movie = [AVPlayer playerWithURL:url]; if ([mOrientation isEqualToString:@"landscape"]) { moviePlayer = [[LandscapeAVPlayerViewController alloc] init]; @@ -199,11 +202,11 @@ -(void)startPlayer:(NSString*)uri { [moviePlayer.player play]; }]; - // Listen for playback finishing - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(moviePlayBackDidFinish:) - name:AVPlayerItemDidPlayToEndTimeNotification - object:moviePlayer.player.currentItem]; + // Listen for playback finishing + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(moviePlayBackDidFinish:) + name:AVPlayerItemDidPlayToEndTimeNotification + object:moviePlayer.player.currentItem]; // Listen for errors [[NSNotificationCenter defaultCenter] addObserver:self @@ -211,7 +214,15 @@ -(void)startPlayer:(NSString*)uri { name:AVPlayerItemFailedToPlayToEndTimeNotification object:moviePlayer.player.currentItem]; - // Listen for click on the "Done" button + + if (imageView != nil) { + [moviePlayer.contentOverlayView setAutoresizesSubviews:YES]; + [moviePlayer.contentOverlayView addSubview:imageView]; + } + moviePlayer.contentOverlayView.backgroundColor = backgroundColor; + [self.viewController.view addSubview:moviePlayer.view]; + + // Listen for click on the "Done" button // Deprecated.. AVPlayerController doesn't offer a "Done" listener... thanks apple. We'll listen for an error when playback finishes // [[NSNotificationCenter defaultCenter] addObserver:self @@ -219,69 +230,69 @@ -(void)startPlayer:(NSString*)uri { // name:MPMoviePlayerWillExitFullscreenNotification // object:nil]; - // Listen for orientation change - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(orientationChanged:) - name:UIDeviceOrientationDidChangeNotification - object:nil]; + // Listen for orientation change + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationChanged:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; + - } - (void) moviePlayBackDidFinish:(NSNotification*)notification { NSLog(@"Playback did finish with auto close being %d, and error message being %@", shouldAutoClose, notification.userInfo); - NSDictionary *notificationUserInfo = [notification userInfo]; - NSNumber *errorValue = [notificationUserInfo objectForKey:AVPlayerItemFailedToPlayToEndTimeErrorKey]; - NSString *errorMsg; - if (errorValue) { - NSError *mediaPlayerError = [notificationUserInfo objectForKey:@"error"]; - if (mediaPlayerError) { - errorMsg = [mediaPlayerError localizedDescription]; - } else { - errorMsg = @"Unknown error."; - } - NSLog(@"Playback failed: %@", errorMsg); - } - - if (shouldAutoClose || [errorMsg length] != 0) { - [self cleanup]; - CDVPluginResult* pluginResult; - if ([errorMsg length] != 0) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMsg]; - } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:true]; - } - [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; - } + NSDictionary *notificationUserInfo = [notification userInfo]; + NSNumber *errorValue = [notificationUserInfo objectForKey:AVPlayerItemFailedToPlayToEndTimeErrorKey]; + NSString *errorMsg; + if (errorValue) { + NSError *mediaPlayerError = [notificationUserInfo objectForKey:@"error"]; + if (mediaPlayerError) { + errorMsg = [mediaPlayerError localizedDescription]; + } else { + errorMsg = @"Unknown error."; + } + NSLog(@"Playback failed: %@", errorMsg); + } + + if (shouldAutoClose || [errorMsg length] != 0) { + [self cleanup]; + CDVPluginResult* pluginResult; + if ([errorMsg length] != 0) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMsg]; + } else { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:true]; + } + [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; + } } - (void)cleanup { - NSLog(@"Clean up"); - imageView = nil; + NSLog(@"Clean up"); + imageView = nil; initFullscreen = false; - backgroundColor = nil; - - // Remove playback finished listener - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:AVPlayerItemDidPlayToEndTimeNotification - object:moviePlayer.player.currentItem]; - // Remove playback finished error listener - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:AVPlayerItemFailedToPlayToEndTimeNotification - object:moviePlayer.player.currentItem]; - // Remove orientation change listener - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:UIDeviceOrientationDidChangeNotification - object:nil]; - - if (moviePlayer) { + backgroundColor = nil; + + // Remove playback finished listener + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:AVPlayerItemDidPlayToEndTimeNotification + object:moviePlayer.player.currentItem]; + // Remove playback finished error listener + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:AVPlayerItemFailedToPlayToEndTimeNotification + object:moviePlayer.player.currentItem]; + // Remove orientation change listener + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIDeviceOrientationDidChangeNotification + object:nil]; + + if (moviePlayer) { [moviePlayer.player pause]; [moviePlayer dismissViewControllerAnimated:YES completion:nil]; - moviePlayer = nil; - } + moviePlayer = nil; + } } @end