diff --git a/README.md b/README.md index 962cb90..37ae584 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,60 @@ -#Cordova YoutubeVideoPlayer Plugin +# Cordova YoutubeVideoPlayer Plugin **Play Youtube Videos in a native Video Player on Android & iOS.** +**This fork works on Android 6, and does not force landscape mode on Android.** + + iOS plugin uses **XCDYouTubeKit** by Cédric Luthi: https://github.com/0xced/XCDYouTubeKit -Android version uses **OpenYoutubeActivity** by Keyes Labs: +Android version (up to 4.4) uses **OpenYoutubeActivity** by Keyes Labs: https://code.google.com/p/android-youtube-player -##Installation +Android version (5.0+) uses YouTube Android Player API: +https://developers.google.com/youtube/android/player/reference/com/google/android/youtube/player/YouTubePlayer + +Android with YouTube App Version 111662130 requires a workaround to resolve an App issue: +https://code.google.com/p/gdata-issues/issues/detail?id=8244 + +## Installation ```sh -cordova plugin add https://github.com/Glitchbone/CordovaYoutubeVideoPlayer.git +cordova plugin add https://github.com/JonSmart/CordovaYoutubeVideoPlayer ``` -##Usage +## Usage ```javascript -YoutubeVideoPlayer.openVideo('YOUTUBE_VIDEO_ID'); +YoutubeVideoPlayer.openVideo('YOUTUBE_VIDEO_ID', function(result) { console.log('YoutubeVideoPlayer result = ' + result); }); ``` -##Author +For Android 5.0+ you will need to add the following to config.xml + +```xml + +``` +with your own YouTube Key. + + For more information: https://developers.google.com/youtube/v3/getting-started + +The callback is called when the video window is closed. (Work in Progress - should be working for IOS). + +## Author **Adrien Glitchbone** + [https://twitter.com/glitchbone](https://twitter.com/glitchbone) + [http://github.com/Glitchbone](http://github.com/Glitchbone) -##License +**d0cz** ++ [http://github.com/d0cz](http://github.com/d0cz) + +**trakout** ++ [https://github.com/trakout](https://github.com/trakout) + +## License CordovaYoutubeVideoPlayer is available under the MIT license. See the [LICENSE](LICENSE) file for more information. XCDYouTubeKit is available under the MIT license. -OpenYoutubeActivity is available under the Apache License 2.0. \ No newline at end of file +OpenYoutubeActivity is available under the Apache License 2.0. diff --git a/config.xml b/config.xml index 21053e3..c0bef56 100644 --- a/config.xml +++ b/config.xml @@ -1,8 +1,8 @@ - + YoutubeVideoPlayerProject - A sample Apache Cordova application that responds to the deviceready event. + Sample Cordova You Tube Player App. Apache Cordova Team diff --git a/package.json b/package.json new file mode 100755 index 0000000..8a02054 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "com.bunkerpalace.cordova.YoutubeVideoPlayer", + "version": "1.0.1", + "cordova": { + "id": "com.bunkerpalace.cordova.YoutubeVideoPlayer", + "platforms": [ + "android", + "ios" + ] + }, + "engines": { + "cordovaDependencies": { + } + } +} diff --git a/platforms/android/AndroidManifest.xml b/platforms/android/AndroidManifest.xml index 7a3c7c9..80459cd 100644 --- a/platforms/android/AndroidManifest.xml +++ b/platforms/android/AndroidManifest.xml @@ -9,7 +9,8 @@ - + + diff --git a/platforms/android/assets/www/js/index.js b/platforms/android/assets/www/js/index.js index 417115c..b3765a9 100644 --- a/platforms/android/assets/www/js/index.js +++ b/platforms/android/assets/www/js/index.js @@ -9,6 +9,6 @@ var app = { }, playVideo: function() { - YoutubeVideoPlayer.openVideo('npjF032TDDQ'); + YoutubeVideoPlayer.openVideo('npjF032TDDQ', function(result) { console.log('YoutubeVideoPlayer result = ' + result); }); } }; diff --git a/platforms/android/libs/YouTubeAndroidPlayerApi.jar b/platforms/android/libs/YouTubeAndroidPlayerApi.jar new file mode 100644 index 0000000..0acbebd Binary files /dev/null and b/platforms/android/libs/YouTubeAndroidPlayerApi.jar differ diff --git a/platforms/android/src/com/bunkerpalace/cordova/YouTubeActivity.java b/platforms/android/src/com/bunkerpalace/cordova/YouTubeActivity.java new file mode 100644 index 0000000..32511af --- /dev/null +++ b/platforms/android/src/com/bunkerpalace/cordova/YouTubeActivity.java @@ -0,0 +1,79 @@ +package com.bunkerpalace.cordova; + +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.widget.Toast; +import com.google.android.youtube.player.YouTubeBaseActivity; +import com.google.android.youtube.player.YouTubeInitializationResult; +import com.google.android.youtube.player.YouTubePlayer; +import com.google.android.youtube.player.YouTubePlayer.Provider; +import com.google.android.youtube.player.YouTubePlayerView; +import com.google.android.youtube.player.YouTubePlayer.PlayerStateChangeListener; + +public class YouTubeActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener, + PlayerStateChangeListener { + + private static final int RECOVERY_REQUEST = 1; + private YouTubePlayerView youTubeView; + private String videoId; + private String apiKey; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Intent intent = getIntent(); + videoId = intent.getStringExtra("videoId"); + apiKey = intent.getStringExtra("YouTubeApiId"); + youTubeView = new YouTubePlayerView(this); + youTubeView.initialize(apiKey, this); + setContentView(youTubeView); + } + + @Override + public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean wasRestored) { + if (!wasRestored) { + player.loadVideo(videoId); + player.setPlayerStateChangeListener(this); + } + } + + @Override + public void onInitializationFailure(Provider provider, YouTubeInitializationResult errorReason) { + if (errorReason.isUserRecoverableError()) { + errorReason.getErrorDialog(this, RECOVERY_REQUEST).show(); + } else { + String error = String.format("Error initializing YouTube player", errorReason.toString()); + Toast.makeText(this, error, Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onVideoEnded() { + setResult(RESULT_OK); + finish(); + } + + @Override + public void onError( + com.google.android.youtube.player.YouTubePlayer.ErrorReason arg0) { + updateLog("onError(): " + arg0.toString()); + finish(); + } + + @Override + public void onAdStarted() {} + + @Override + public void onLoaded(String arg0) {} + + @Override + public void onLoading() {} + + @Override + public void onVideoStarted() {} + + private void updateLog(String text){ + Log.d("YouTubeActivity", text); + }; +} diff --git a/platforms/android/src/com/bunkerpalace/cordova/YoutubeVideoPlayer.java b/platforms/android/src/com/bunkerpalace/cordova/YoutubeVideoPlayer.java index 4bcbb5a..36fa86c 100644 --- a/platforms/android/src/com/bunkerpalace/cordova/YoutubeVideoPlayer.java +++ b/platforms/android/src/com/bunkerpalace/cordova/YoutubeVideoPlayer.java @@ -1,33 +1,73 @@ package com.bunkerpalace.cordova; + import org.apache.cordova.CallbackContext; +import org.apache.cordova.ConfigXmlParser; import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.CordovaPreferences; +import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; - +import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.util.Log; - +import com.google.android.youtube.player.YouTubeIntents; import com.keyes.youtube.OpenYouTubePlayerActivity; +import android.os.Build; +import android.util.Log; public class YoutubeVideoPlayer extends CordovaPlugin { + private CallbackContext callbackContext; + @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if(action.equals("openVideo")) { String url = args.getString(0); - this.openVideo(url, callbackContext); + this.openVideo(url); + this.callbackContext = callbackContext; return true; - } - + } return false; } - - private void openVideo(String vid, CallbackContext callbackContext) { - - Intent intent = new Intent(null, Uri.parse("ytv://"+vid), this.cordova.getActivity(), OpenYouTubePlayerActivity.class); - this.cordova.getActivity().startActivity(intent); + + public void onActivityResult(int requestCode, int resultCode, Intent intent) { + if (requestCode == 242) { + if (resultCode == this.cordova.getActivity().RESULT_OK) { + this.callbackContext.success(); + } else { + this.callbackContext.error("Error"); + } + } + } + + private void openVideo(String videoId) { + Intent intent = createYoutubeIntent(videoId); + cordova.startActivityForResult(this, intent, 242); + } + + private Intent createYoutubeIntent(String videoId) { + if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){ + Intent intent; + Context cordovaContext = cordova.getActivity(); + String version = YouTubeIntents.getInstalledYouTubeVersionName(cordovaContext); + if(version.startsWith("11.16") && YouTubeIntents.canResolvePlayVideoIntent(cordovaContext)) { + intent = YouTubeIntents.createPlayVideoIntent(cordovaContext, videoId); + } else { + if(YouTubeIntents.canResolvePlayVideoIntentWithOptions(cordovaContext)){ + intent = YouTubeIntents.createPlayVideoIntentWithOptions(cordovaContext, videoId, true, true); + } else { + intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com/watch?v=" + videoId), cordovaContext, YouTubeActivity.class); + intent.putExtra("videoId", videoId); + ConfigXmlParser parser = new ConfigXmlParser(); + parser.parse(cordovaContext); + CordovaPreferences prefs = parser.getPreferences(); + intent.putExtra("YouTubeApiId", prefs.getString("YouTubeDataApiKey","YOUTUBE_API_KEY")); + } + } + return intent; + } + + return new Intent(null, Uri.parse("ytv://" + videoId), cordova.getActivity(), OpenYouTubePlayerActivity.class); } - } diff --git a/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.h b/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.h index 3787736..bd25e69 100644 --- a/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.h +++ b/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.h @@ -8,7 +8,9 @@ #import #import "XCDYouTubeVideoPlayerViewController.h" -@interface YoutubeVideoPlayer : CDVPlugin +@interface YoutubeVideoPlayer : CDVPlugin { + NSString* _eventsCallbackId; +} - (void)openVideo:(CDVInvokedUrlCommand*)command; diff --git a/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.m b/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.m index 2405f0c..72d8b60 100644 --- a/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.m +++ b/platforms/ios/YoutubeVideoPlayerProject/Plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/YoutubeVideoPlayer.m @@ -20,6 +20,8 @@ - (void)openVideo:(CDVInvokedUrlCommand*)command if (videoID != nil) { XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:videoID]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerPlaybackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayerViewController.moviePlayer]; + [self.viewController presentMoviePlayerViewControllerAnimated:videoPlayerViewController]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; @@ -27,10 +29,30 @@ - (void)openVideo:(CDVInvokedUrlCommand*)command } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Missing videoID Argument"]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + _eventsCallbackId = command.callbackId; +} + +- (void) moviePlayerPlaybackDidFinish:(NSNotification *)notification +{ + CDVPluginResult* pluginResult = nil; + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + + + [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:notification.object]; + MPMovieFinishReason finishReason = [notification.userInfo[MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] integerValue]; + if (finishReason == MPMovieFinishReasonPlaybackError) + { + NSError *error = notification.userInfo[XCDMoviePlayerPlaybackDidFinishErrorUserInfoKey]; + // Handle error + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Playback Error"]; + } + + [self.commandDelegate sendPluginResult:pluginResult callbackId:_eventsCallbackId]; + } @end diff --git a/platforms/ios/www/js/index.js b/platforms/ios/www/js/index.js index 417115c..0b53d71 100644 --- a/platforms/ios/www/js/index.js +++ b/platforms/ios/www/js/index.js @@ -9,6 +9,6 @@ var app = { }, playVideo: function() { - YoutubeVideoPlayer.openVideo('npjF032TDDQ'); + YoutubeVideoPlayer.openVideo('npjF032TDDQ', function(result) { console.log('YoutubeVideoPlayer result = ' + result); }); } }; diff --git a/platforms/ios/www/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js b/platforms/ios/www/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js index 764f240..90ab61d 100644 --- a/platforms/ios/www/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js +++ b/platforms/ios/www/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js @@ -2,12 +2,18 @@ cordova.define("com.bunkerpalace.cordova.YoutubeVideoPlayer.YoutubeVideoPlayer", function YoutubeVideoPlayer() {} -YoutubeVideoPlayer.prototype.openVideo = function(YTid) { +YoutubeVideoPlayer.prototype.openVideo = function(YTid, callback) { exec(function(result) { console.log(result); + if(callback){ + callback('closed'); + } }, function(error) { console.log(error); + if(callback){ + callback('error'); + } }, "YoutubeVideoPlayer", "openVideo", diff --git a/plugin.xml b/plugin.xml index 77b74e5..80a83e7 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,77 +1,84 @@ - + CordovaYoutubeVideoPlayer - Play Youtube Videos in a native Video Player on Android & iOS. - - Adrien Glitchbone - Bunker Palace SA - - video,youtube,videoplayer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Play Youtube Videos in a native Video Player on Android & iOS. + + Adrien Glitchbone - Bunker Palace SA + + video,youtube,videoplayer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js b/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js index eb3a09f..ac2820d 100644 --- a/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js +++ b/plugins/com.bunkerpalace.cordova.YoutubeVideoPlayer/www/YoutubeVideoPlayer.js @@ -2,12 +2,18 @@ var exec = require('cordova/exec'); function YoutubeVideoPlayer() {} -YoutubeVideoPlayer.prototype.openVideo = function(YTid) { +YoutubeVideoPlayer.prototype.openVideo = function(YTid, callback) { exec(function(result) { console.log(result); + if(callback){ + callback('closed'); + } }, function(error) { console.log(error); + if(callback){ + callback('error'); + } }, "YoutubeVideoPlayer", "openVideo", diff --git a/www/js/index.js b/www/js/index.js index 417115c..b3765a9 100644 --- a/www/js/index.js +++ b/www/js/index.js @@ -9,6 +9,6 @@ var app = { }, playVideo: function() { - YoutubeVideoPlayer.openVideo('npjF032TDDQ'); + YoutubeVideoPlayer.openVideo('npjF032TDDQ', function(result) { console.log('YoutubeVideoPlayer result = ' + result); }); } };