Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added setPlaybackRate and tracks #63

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions src/android/Chromecast.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import android.util.Log;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
Expand Down Expand Up @@ -299,12 +302,12 @@ public boolean addMessageListener(String namespace, CallbackContext callbackCont
* @param callbackContext called with .success or .error depending on the result
* @return true for cordova
*/
public boolean loadMedia(String contentId, JSONObject customData, String contentType, Integer duration, String streamType, Boolean autoPlay, Integer currentTime, JSONObject metadata, JSONObject textTrackStyle, final CallbackContext callbackContext) {
return this.loadMedia(contentId, customData, contentType, duration, streamType, autoPlay, new Double(currentTime.doubleValue()), metadata, textTrackStyle, callbackContext);
public boolean loadMedia(String contentId, JSONObject customData, String contentType, Integer duration, String streamType, Boolean autoPlay, Integer currentTime, JSONObject metadata, JSONObject textTrackStyle, JSONArray tracks, final CallbackContext callbackContext) {
return this.loadMedia(contentId, customData, contentType, duration, streamType, autoPlay, new Double(currentTime.doubleValue()), metadata, textTrackStyle, tracks, callbackContext);
}

private boolean loadMedia(String contentId, JSONObject customData, String contentType, Integer duration, String streamType, Boolean autoPlay, Double currentTime, JSONObject metadata, JSONObject textTrackStyle, final CallbackContext callbackContext) {
this.media.loadMedia(contentId, customData, contentType, duration, streamType, autoPlay, currentTime, metadata, textTrackStyle, callbackContext);
private boolean loadMedia(String contentId, JSONObject customData, String contentType, Integer duration, String streamType, Boolean autoPlay, Double currentTime, JSONObject metadata, JSONObject textTrackStyle, JSONArray tracks, final CallbackContext callbackContext) {
this.media.loadMedia(contentId, customData, contentType, duration, streamType, autoPlay, currentTime, metadata, textTrackStyle, tracks, callbackContext);
return true;
}

Expand All @@ -318,6 +321,16 @@ public boolean mediaPlay(CallbackContext callbackContext) {
return true;
}

/**
* Play on the current media in the current session.
* @param callbackContext called with .success or .error depending on the result
* @return true for cordova
*/
public boolean setMediaPlayBackRate(String playbackRate, CallbackContext callbackContext) {
media.setPlayBackRate(playbackRate, callbackContext);
return true;
}

/**
* Pause on the current media in the current session.
* @param callbackContext called with .success or .error depending on the result
Expand Down
23 changes: 21 additions & 2 deletions src/android/ChromecastSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
Expand Down Expand Up @@ -219,14 +220,14 @@ public void onResult(Status result) {
* @param textTrackStyle - The text track style
* @param callback called with success or error
*/
public void loadMedia(String contentId, JSONObject customData, String contentType, long duration, String streamType, boolean autoPlay, double currentTime, JSONObject metadata, JSONObject textTrackStyle, CallbackContext callback) {
public void loadMedia(String contentId, JSONObject customData, String contentType, long duration, String streamType, boolean autoPlay, double currentTime, JSONObject metadata, JSONObject textTrackStyle, JSONArray tracks, CallbackContext callback) {
if (client == null || session == null) {
callback.error("session_error");
return;
}
activity.runOnUiThread(new Runnable() {
public void run() {
MediaInfo mediaInfo = ChromecastUtilities.createMediaInfo(contentId, customData, contentType, duration, streamType, metadata, textTrackStyle);
MediaInfo mediaInfo = ChromecastUtilities.createMediaInfo(contentId, customData, contentType, duration, streamType, metadata, textTrackStyle, tracks);
MediaLoadRequestData loadRequest = new MediaLoadRequestData.Builder()
.setMediaInfo(mediaInfo)
.setAutoplay(autoPlay)
Expand Down Expand Up @@ -271,6 +272,24 @@ public void run() {
});
}

/**
* Media API - Calls play on the current media.
* @param callback called with success or error
*/
public void setPlayBackRate(String playbackRate, CallbackContext callback) {
if (client == null || session == null) {
callback.error("session_error");
return;
}
activity.runOnUiThread(new Runnable() {
public void run() {
Double d = Double.valueOf(playbackRate);
client.setPlaybackRate(d)
.setResultCallback(getResultCallback(callback, "Failed to setPlaybackRate."));
}
});
}

/**
* Media API - Calls pause on the current media.
* @param callback called with success or error
Expand Down
26 changes: 24 additions & 2 deletions src/android/ChromecastUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.graphics.Color;
import android.net.Uri;
import java.util.ArrayList;

import androidx.annotation.NonNull;
import androidx.mediarouter.media.MediaRouter;
Expand Down Expand Up @@ -827,6 +828,7 @@ static MediaInfo createMediaInfo(JSONObject mediaInfo) {
String streamType = "unknown";
JSONObject metadata = new JSONObject();
JSONObject textTrackStyle = new JSONObject();
JSONArray tracks = new JSONArray();

// Try to get the actual values
try {
Expand Down Expand Up @@ -858,10 +860,10 @@ static MediaInfo createMediaInfo(JSONObject mediaInfo) {
} catch (JSONException e) {
}

return createMediaInfo(contentId, customData, contentType, duration, streamType, metadata, textTrackStyle);
return createMediaInfo(contentId, customData, contentType, duration, streamType, metadata, textTrackStyle, tracks);
}

static MediaInfo createMediaInfo(String contentId, JSONObject customData, String contentType, long duration, String streamType, JSONObject metadata, JSONObject textTrackStyle) {
static MediaInfo createMediaInfo(String contentId, JSONObject customData, String contentType, long duration, String streamType, JSONObject metadata, JSONObject textTrackStyle, JSONArray tracks) {
MediaInfo.Builder mediaInfoBuilder = new MediaInfo.Builder(contentId);

mediaInfoBuilder.setMetadata(createMediaMetadata(metadata));
Expand All @@ -887,6 +889,26 @@ static MediaInfo createMediaInfo(String contentId, JSONObject customData, String
.setStreamDuration(duration)
.setTextTrackStyle(trackStyle);

if (tracks != null) {
List mediaTracks = new ArrayList();

for (int i = 0; i < tracks.length(); i++) {
try {
JSONObject track = tracks.getJSONObject(i);
MediaTrack mediaTrack = new MediaTrack.Builder(track.getInt("trackId"), MediaTrack.TYPE_TEXT)
.setName(track.getString("name"))
.setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
.setContentId(track.getString("trackContentId"))
.setLanguage(track.getString("language"))
.build();
mediaTracks.add(mediaTrack);
} catch (JSONException e) {
}
}

mediaInfoBuilder.setMediaTracks(mediaTracks);
}

return mediaInfoBuilder.build();
}

Expand Down
2 changes: 1 addition & 1 deletion src/ios/MLPCastUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN

@interface MLPCastUtilities : NSObject

+(GCKMediaInformation *)buildMediaInformation:(NSString *)contentUrl customData:(id )customData contentType:(NSString *)contentType duration:(double)duration streamType:(NSString *)streamType startTime:(double)startTime metaData:(NSDictionary *)metaData textTrackStyle:(NSDictionary *)textTrackStyle;
+(GCKMediaInformation *)buildMediaInformation:(NSString *)contentUrl customData:(id )customData contentType:(NSString *)contentType duration:(double)duration streamType:(NSString *)streamType startTime:(double)startTime metaData:(NSDictionary *)metaData textTrackStyle:(NSDictionary *)textTrackStyle tracks:(NSArray *)tracks;
+(GCKMediaQueueItem *)buildMediaQueueItem:(NSDictionary *)item;
+ (GCKMediaTextTrackStyle *)buildTextTrackStyle:(NSDictionary *)data;
+(GCKMediaMetadata*)buildMediaMetadata:(NSDictionary*)data;
Expand Down
29 changes: 22 additions & 7 deletions src/ios/MLPCastUtilities.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ @implementation MLPCastUtilities

NSDictionary* queueOrderIDsByItemId = nil;

+ (GCKMediaInformation *)buildMediaInformation:(NSString *)contentUrl customData:(id )customData contentType:(NSString *)contentType duration:(double)duration streamType:(NSString *)streamType startTime:(double)startTime metaData:(NSDictionary *)metaData textTrackStyle:(NSDictionary *)textTrackStyle {
+ (GCKMediaInformation *)buildMediaInformation:(NSString *)contentUrl customData:(id )customData contentType:(NSString *)contentType duration:(double)duration streamType:(NSString *)streamType startTime:(double)startTime metaData:(NSDictionary *)metaData textTrackStyle:(NSDictionary *)textTrackStyle tracks:(NSArray *)tracks {
NSURL* url = [NSURL URLWithString:contentUrl];

GCKMediaInformationBuilder* mediaInfoBuilder = [[GCKMediaInformationBuilder alloc] initWithContentURL:url];
Expand All @@ -26,7 +26,23 @@ + (GCKMediaInformation *)buildMediaInformation:(NSString *)contentUrl customData
mediaInfoBuilder.startAbsoluteTime = startTime;
mediaInfoBuilder.metadata = [MLPCastUtilities buildMediaMetadata:metaData];
mediaInfoBuilder.textTrackStyle = [MLPCastUtilities buildTextTrackStyle:textTrackStyle];


if (tracks != (id)[NSNull null]) {
NSMutableArray<GCKMediaTrack*>* mediaTracks = [NSMutableArray new];
for (id track in tracks) {
GCKMediaTrack *mediaTrack = [[GCKMediaTrack alloc] initWithIdentifier:[track[@"trackId"] intValue]
contentIdentifier:track[@"trackContentId"]
contentType:track[@"trackContentType"]
type:GCKMediaTrackTypeText
textSubtype:GCKMediaTextTrackSubtypeCaptions
name:track[@"name"]
languageCode:track[@"language"]
customData:track[@"customData"]];
[mediaTracks addObject:mediaTrack];
}
mediaInfoBuilder.mediaTracks = mediaTracks;
}

return [mediaInfoBuilder build];
}

Expand All @@ -42,7 +58,7 @@ + (GCKMediaQueueItem *)buildMediaQueueItem:(NSDictionary *)item {
queueItemBuilder.startTime = startTime;
queueItemBuilder.preloadTime = [item[@"preloadTime"] doubleValue];

queueItemBuilder.mediaInformation = [MLPCastUtilities buildMediaInformation:media[@"contentId"] customData:media[@"customData"] contentType:media[@"contentType"] duration:duration streamType:media[@"streamType"] startTime:startTime metaData:media[@"metadata"] textTrackStyle:item[@"textTrackStyle"]];
queueItemBuilder.mediaInformation = [MLPCastUtilities buildMediaInformation:media[@"contentId"] customData:media[@"customData"] contentType:media[@"contentType"] duration:duration streamType:media[@"streamType"] startTime:startTime metaData:media[@"metadata"] textTrackStyle:item[@"textTrackStyle"] tracks:item[@"tracks"]];

return [queueItemBuilder build];
}
Expand All @@ -52,22 +68,21 @@ + (GCKMediaTextTrackStyle *)buildTextTrackStyle:(NSDictionary *)data {
GCKMediaTextTrackStyle* mediaTextTrackStyle = [GCKMediaTextTrackStyle createDefault];

if (error == nil) {
NSString* bkgColor = data[@"backgroundColor"];
// Not working dictionary
// NSString* bkgColor = data[@"backgroundColor"];
NSString* bkgColor = @"#000000fa";
if (bkgColor != nil) {
mediaTextTrackStyle.backgroundColor = [[GCKColor alloc] initWithCSSString:bkgColor];

}

NSObject* customData = data[@"customData"];
if (bkgColor != nil) {
mediaTextTrackStyle.customData = customData;

}

NSString* edgeColor = data[@"edgeColor"];
if (edgeColor != nil) {
mediaTextTrackStyle.edgeColor = [[GCKColor alloc] initWithCSSString:edgeColor];

}

NSString* edgeType = data[@"edgeType"];
Expand Down
2 changes: 1 addition & 1 deletion src/ios/MLPChromecast.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)addMessageListener:(CDVInvokedUrlCommand*)command;
- (void)sendMessage:(CDVInvokedUrlCommand*) command;
- (void)mediaPlay:(CDVInvokedUrlCommand*)command;
- (void)mediaPause:(CDVInvokedUrlCommand*)command;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think mediaPause should be removed here?

- (void)setMediaPlayBackRate:(CDVInvokedUrlCommand*)command;
- (void)mediaSeek:(CDVInvokedUrlCommand*)command;
- (void)mediaStop:(CDVInvokedUrlCommand*)command;
- (void)mediaEditTracksInfo:(CDVInvokedUrlCommand*)command;
Expand Down
9 changes: 7 additions & 2 deletions src/ios/MLPChromecast.m
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ - (void)loadMedia:(CDVInvokedUrlCommand*) command {
double currentTime = [command.arguments[6] doubleValue];
NSDictionary* metadata = command.arguments[7];
NSDictionary* textTrackStyle = command.arguments[8];
GCKMediaInformation* mediaInfo = [MLPCastUtilities buildMediaInformation:contentId customData:customData contentType:contentType duration:duration streamType:streamType startTime:currentTime metaData:metadata textTrackStyle:textTrackStyle];
NSArray* tracks = command.arguments[9];
GCKMediaInformation* mediaInfo = [MLPCastUtilities buildMediaInformation:contentId customData:customData contentType:contentType duration:duration streamType:streamType startTime:currentTime metaData:metadata textTrackStyle:textTrackStyle tracks:tracks];

[self.currentSession loadMediaWithCommand:command mediaInfo:mediaInfo autoPlay:autoplay currentTime:currentTime];
}
Expand All @@ -288,6 +289,10 @@ - (void)mediaPlay:(CDVInvokedUrlCommand*)command {
[self.currentSession mediaPlayWithCommand:command];
}

- (void)setMediaPlayBackRate:(CDVInvokedUrlCommand*)command {
NSString* playbackRate = command.arguments[0];
[self.currentSession sendPlaybackRateWithCommand:command playbackRate:playbackRate];
}
- (void)mediaPause:(CDVInvokedUrlCommand*)command {
[self.currentSession mediaPauseWithCommand:command];
}
Expand All @@ -305,7 +310,7 @@ - (void)mediaStop:(CDVInvokedUrlCommand*)command {

- (void)mediaEditTracksInfo:(CDVInvokedUrlCommand*)command {
NSArray<NSNumber*>* activeTrackIds = command.arguments[0];
NSData* textTrackStyle = command.arguments[1];
NSDictionary* textTrackStyle = command.arguments[1];

GCKMediaTextTrackStyle* textTrackStyleObject = [MLPCastUtilities buildTextTrackStyle:textTrackStyle];
[self.currentSession setActiveTracksWithCommand:command activeTrackIds:activeTrackIds textTrackStyle:textTrackStyleObject];
Expand Down
1 change: 1 addition & 0 deletions src/ios/MLPChromecastSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)mediaSeekWithCommand:(CDVInvokedUrlCommand*)command position:(NSTimeInterval)position resumeState:(GCKMediaResumeState)resumeState;
- (void)mediaPlayWithCommand:(CDVInvokedUrlCommand*)command;
- (void)mediaPauseWithCommand:(CDVInvokedUrlCommand*)command;
- (void)sendPlaybackRateWithCommand:(CDVInvokedUrlCommand*)command playbackRate:(NSString*)playbackRate;
- (void)mediaStopWithCommand:(CDVInvokedUrlCommand*)command;
- (void)setActiveTracksWithCommand:(CDVInvokedUrlCommand*)command activeTrackIds:(NSArray<NSNumber*>*)activeTrackIds textTrackStyle:(GCKMediaTextTrackStyle*)textTrackStyle;
- (void)queueLoadItemsWithCommand:(CDVInvokedUrlCommand *)command queueItems:(NSArray *)queueItems startIndex:(NSInteger)startIndex repeatMode:(GCKMediaRepeatMode)repeatMode;
Expand Down
6 changes: 6 additions & 0 deletions src/ios/MLPChromecastSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ - (void)mediaPauseWithCommand:(CDVInvokedUrlCommand*)command {
request.delegate = [self createMediaUpdateRequestDelegate:command];
}

- (void)sendPlaybackRateWithCommand:(CDVInvokedUrlCommand*)command playbackRate:(NSString*)playbackRate {
float playbackRateFloat = [playbackRate floatValue];
GCKRequest* request = [self.remoteMediaClient setPlaybackRate:playbackRateFloat];
request.delegate = [self createMediaUpdateRequestDelegate:command];
}

- (void)mediaStopWithCommand:(CDVInvokedUrlCommand*)command {
GCKRequest* request = [self.remoteMediaClient stop];
request.delegate = [self createMediaUpdateRequestDelegate:command];
Expand Down
15 changes: 13 additions & 2 deletions www/chrome.cast.js
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ chrome.cast.Session.prototype.loadMedia = function (loadRequest, successCallback
var self = this;

var mediaInfo = loadRequest.media;
execute('loadMedia', mediaInfo.contentId, mediaInfo.customData || {}, mediaInfo.contentType, mediaInfo.duration || 0.0, mediaInfo.streamType, loadRequest.autoplay || false, loadRequest.currentTime || 0, mediaInfo.metadata || {}, mediaInfo.textTrackSytle || {}, function (err, obj) {
execute('loadMedia', mediaInfo.contentId, mediaInfo.customData || {}, mediaInfo.contentType, mediaInfo.duration || 0.0, mediaInfo.streamType, loadRequest.autoplay || false, loadRequest.currentTime || 0, mediaInfo.metadata || {}, mediaInfo.textTrackSytle || {}, mediaInfo.tracks || null, function (err, obj) {
if (!err) {
self._loadNewMedia(obj);
successCallback(self._getMedia());
Expand Down Expand Up @@ -1100,10 +1100,21 @@ chrome.cast.media.Media.prototype.play = function (playRequest, successCallback,
});
};

chrome.cast.media.Media.prototype.setPlayBackRate = function (playBackRate, successCallback, errorCallback) {
if (this._preCheck(errorCallback)) { return; }
execute('setMediaPlayBackRate', playBackRate, function (err) {
if (!err) {
successCallback && successCallback();
} else {
handleError(err, errorCallback);
}
});
};

/**
* Pauses the media item.
* @param {chrome.cast.media.PauseRequest} pauseRequest The optional media pause request.
* @param {function} successCallback Invoked on success.
* @param {function} \ successCallback Invoked on success.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo '/' here

* @param {function} errorCallback Invoked on error. The possible errors are TIMEOUT, API_NOT_INITIALIZED, INVALID_PARAMETER, CHANNEL_ERROR, SESSION_ERROR, and EXTENSION_MISSING.
*/
chrome.cast.media.Media.prototype.pause = function (pauseRequest, successCallback, errorCallback) {
Expand Down