Skip to content
This repository has been archived by the owner on Nov 24, 2023. It is now read-only.

Commit

Permalink
Plugin implementation (#1)
Browse files Browse the repository at this point in the history
* Similar behaviors for Android & iOS
* Updated README with arguments type for callbacks
  • Loading branch information
davidefavia authored Apr 4, 2017
1 parent 3b9ac6a commit be7eee9
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 26 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# v1.0.0 (2017-04-04)

First release.
82 changes: 56 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# cordova-plugin-in-app-youtube

Open YouTube video in app or using the browser as fallback for Android & iOS.
Open YouTube video in app or use the browser as fallback for Android & iOS. Plugin goal is to show YouTube video via native app or mobile website to count for views.

If you need to stream YouTube video content without using its own player, just check [Glitchbone/CordovaYoutubeVideoPlayer](https://github.com/Glitchbone/CordovaYoutubeVideoPlayer) project.

## Getting Started

Expand All @@ -9,7 +11,7 @@ This plugin has been tested with Cordova 6.5.0, Android 7.1.1 and iOS 10.3.
Install via Cordova:

```
$ cordova plugin install https://github.com/davidefavia/cordova-plugin-in-app-youtube
$ cordova plugin add https://github.com/davidefavia/cordova-plugin-in-app-youtube
```

## Reference
Expand All @@ -23,34 +25,62 @@ It opens a YouTube video.
|Parameter|Type|Default|Description|
|-|:-:|:-:|-|
|videoId|string||YouTube video identifier, _e.g._ `9bZkp7q19f0`.|
|options|object|{}|Use `fullscreen = true` to enable fullscreen (only Android).|
|successCallback|function|function() {}|Returns plugin result object with videoId, options and type key. type can be `application` or `webview` depending on which application opened the video.|
|errorCallback|function|function() {}|Returns error or exception message.|
|options|object|{}|Use `fullscreen = true` to enable fullscreen.|
|successCallback|function|function() {}|Plugin returns result object with `videoId` (string), `options` (object) and `type` (string) key. `type` can be `application` or `webview` depending on which application opened the video.|
|errorCallback|function|function() {}|Plugin returns error or exception message (string).|

Platforms have different behaviors.

#### Android

- It shows the video using the YouTube activity if the native app is installed. On back button press the native video closes and the WebView gets focus. It is possible to play fullscreen video.
- It opens default web browser if the native YouTube app is not installed.

#### iOS

- It shows the video using the native YouTube app if it is installed. It is NOT possible to play fullscreen video.
- It opens default web browser if the native YouTube app is not installed. There is a back link in the statusbar to go back to Cordova application.

## Versioning

I use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/davidefavia/cordova-plugin-in-app-youtube/tags).

## Author

[davidefavia](https://github.com/davidefavia)
|Platform|YouTube app installed|fullscreen option|Behavior|
|:-:|:-:|:-:|-|
|Android|Yes|true|YouTube app plays video in landscape mode (even if your app forbids this orientation) in fullscreen inside your app. Back button lets Cordova WebView take focus back.|
|Android|Yes|false|YouTube app plays video in portrait mode inside your app. Some related content is shown below the video player. Back button lets the Cordova WebView take focus back.|
|Android|No|true|URL `https://www.youtube.com/embed/<video-id>` is opened in the default browser in full window size, browser toolbar is visible. Video is stopped by default due to Chrome for Android policies.|
|Android|No|false|URL `https://www.youtube.com/watch?v=<video-id>` is opened in the default browser, browser toolbar is visible. Video is stopped by default due to Chrome for Android policies.|
|iOS|Yes|true|YouTube app plays video in portrait mode outside your app. Some related content is shown below the video player. Back button in top corner lets the Cordova WebView take focus back.|
|iOS|Yes|false|YouTube app plays video in portrait mode outside your app. Some related content is shown below the video player. Back button in top corner lets the Cordova WebView take focus back.|
|iOS|No|true|URL `https://www.youtube.com/embed/<video-id>` is opened in the Safari in full window size, toolbar is visible. Video is stopped by default due to Apple policies.|
|iOS|No|false|URL `https://www.youtube.com/watch?v=<video-id>` is opened in the default browser, browser toolbar is visible. Video is stopped by default due to Apple policies.|

## Example

```js
<!DOCTYPE html>
<html>
<head>
<title>Device Ready Example</title>

<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">

// Wait for device API libraries to load
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}

// device APIs are available
function onDeviceReady() {
// Now safe to use device APIs
try {
window.InAppYouTube.openVideo('9bZkp7q19f0', {
fullscreen: true
}, function(result) {
// console.log(JSON.stringify(result));
}, function(reason) {
// console.log(reason);
});
} catch(e) {
// Exception!
}
}

</script>
</head>
<body onload="onLoad()">
</body>
</html>
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

* [https://github.com/Glitchbone/CordovaYoutubeVideoPlayer]
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "cordova-plugin-in-app-youtube",
"version": "1.0.0",
"cordova": {
"id": "cordova-plugin-in-app-youtube",
"platforms": [
"android",
"ios",
]
},
"description": "Open YouTube video in app"
}
47 changes: 47 additions & 0 deletions plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="cordova-plugin-in-app-youtube"
version="1.0.0">
<name>Cordova Plugin in app YouTube</name>
<description></description>
<license>MIT</license>
<keywords></keywords>
<repo>https://github.com/davidefavia/cordova-plugin-in-app-youtube.git</repo>
<issue>https://github.com/davidefavia/cordova-plugin-in-app-youtube/issues</issue>

<!-- android -->
<platform name="android">
<js-module src="www/plugin.js" name="plugin">
<runs/>
<clobbers target="InAppYouTube" />
</js-module>
<config-file target="res/xml/config.xml" parent="/*">
<feature name="InAppYouTube">
<param name="android-package" value="com.davidefavia.InAppYouTube" />
<param name="onload" value="true" />
</feature>
</config-file>
<source-file src="src/android/com/davidefavia/InAppYouTube.java" target-dir="src/com/davidefavia/" />
</platform>

<!-- ios -->
<platform name="ios">
<js-module src="www/plugin.js" name="plugin">
<runs/>
<clobbers target="InAppYouTube" />
</js-module>
<config-file target="config.xml" parent="/*">
<feature name="InAppYouTube">
<param name="ios-package" value="InAppYouTube" onload="true" />
</feature>
</config-file>
<!-- http://stackoverflow.com/a/34963435 -->
<config-file platform="ios" target="*-Info.plist" parent="LSApplicationQueriesSchemes" mode="add">
<array>
<string>youtube</string>
</array>
</config-file>
<header-file src="src/ios/InAppYouTube.h" />
<source-file src="src/ios/InAppYouTube.m" />
</platform>
</plugin>
72 changes: 72 additions & 0 deletions src/android/com/davidefavia/InAppYouTube.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
*/
package com.davidefavia;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PluginResult.Status;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;

import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.content.ActivityNotFoundException;

import java.util.Date;

public class InAppYouTube extends CordovaPlugin {
private static final String TAG = "InAppYouTube";

public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);

Log.d(TAG, "Initializing InAppYouTube");
}

public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
if(action.equals("openVideo")) {
String videoId = args.getString(0);
JSONObject options = args.getJSONObject(1);
this.openVideo(videoId, options, callbackContext);
}
return true;
}

private void openVideo(String videoId, JSONObject options, CallbackContext callbackContext) {
Boolean isFullScreen = options.optBoolean("fullscreen");
String webUrl;
if(isFullScreen) {
webUrl = "https://www.youtube.com/embed/" + videoId;
} else {
webUrl = "https://www.youtube.com/watch?v=" + videoId;
}
Intent appIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube://" + videoId));
Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(webUrl));
Log.d(TAG, "fullscreen: " + String.valueOf(options.optBoolean("fullscreen")));
String type;
try {
appIntent.putExtra("force_fullscreen", isFullScreen);
this.cordova.getActivity().startActivity(appIntent);
type = "application";
} catch (ActivityNotFoundException ex) {
this.cordova.getActivity().startActivity(webIntent);
type = "webview";
}
try {
JSONObject json = new JSONObject();
json.put("videoId", videoId);
json.put("options", options);
json.put("type", type);
callbackContext.success(json);
} catch (JSONException e) {
Log.e(TAG, e.toString());
callbackContext.error(e.toString());
}
}

}
8 changes: 8 additions & 0 deletions src/ios/InAppYouTube.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#import <Cordova/CDVPlugin.h>

@interface InAppYouTube : CDVPlugin {
}

- (void)openVideo:(CDVInvokedUrlCommand *)command;

@end
47 changes: 47 additions & 0 deletions src/ios/InAppYouTube.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#import "InAppYouTube.h"

#import <Cordova/CDVAvailability.h>

@implementation InAppYouTube

- (void)pluginInitialize {
}

- (void)openVideo:(CDVInvokedUrlCommand *)command {
NSString* videoId = [command.arguments objectAtIndex:0];
NSDictionary* options = [command.arguments objectAtIndex:1];
BOOL isFullScreen = [options[@"fullscreen"] boolValue];

NSURL *linkToAppURL = [NSURL URLWithString:[NSString stringWithFormat:@"youtube://watch?v=%@",videoId]];
NSURL *linkToWebURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://www.youtube.com/watch?v=%@",videoId]];
if(isFullScreen) {
linkToWebURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://www.youtube.com/embed/%@",videoId]];
}

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:videoId forKey:@"videoId"];
[dictionary setObject:options forKey:@"options"];

// http://stackoverflow.com/a/35409477
if ([[UIApplication sharedApplication] canOpenURL:linkToAppURL]) {
// @TODO Check for fullscreen
// Can open the youtube app URL so launch the youTube app with this URL
[[UIApplication sharedApplication] openURL:linkToAppURL];
[dictionary setObject:@"application" forKey:@"type"];
} else {
// Can't open the youtube app URL so launch Safari instead
// https://useyourloaf.com/blog/openurl-deprecated-in-ios10/
UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[application openURL:linkToWebURL options:@{} completionHandler:nil];
} else {
[application openURL:linkToWebURL];
}
[dictionary setObject:@"webview" forKey:@"type"];
}

CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}

@end
13 changes: 13 additions & 0 deletions www/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var exec = require('cordova/exec');

var PLUGIN_NAME = 'InAppYouTube';

var noop = function() {};

var InAppYouTube = {
openVideo: function(videoId, options, successCallback, errorCallback) {
exec(successCallback || noop, errorCallback || noop, PLUGIN_NAME, 'openVideo', [videoId, options || {}]);
}
};

module.exports = InAppYouTube;

0 comments on commit be7eee9

Please sign in to comment.