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

[Improvement] Modernize loadPlaylist function with types and logic #98

Merged
merged 3 commits into from
Nov 15, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,45 @@ public void execute (NativeViewHierarchyManager nvhm) {
}
}

@ReactMethod
public void loadPlaylist(final int reactTag, final String playlistUrl) {
try {
UIManagerModule uiManager = mReactContext.getNativeModule(UIManagerModule.class);
uiManager.addUIBlock(new UIBlock() {
public void execute (NativeViewHierarchyManager nvhm) {
RNJWPlayerView playerView = (RNJWPlayerView) nvhm.resolveView(reactTag);

if (playerView != null && playerView.mPlayerView != null) {
JWPlayer player = playerView.mPlayerView.getPlayer();

PlayerConfig oldConfig = player.getConfig();
PlayerConfig config = new PlayerConfig.Builder()
.autostart(oldConfig.getAutostart())
.nextUpOffset(oldConfig.getNextUpOffset())
.repeat(oldConfig.getRepeat())
.relatedConfig(oldConfig.getRelatedConfig())
.displayDescription(oldConfig.getDisplayDescription())
.displayTitle(oldConfig.getDisplayTitle())
.advertisingConfig(oldConfig.getAdvertisingConfig())
.stretching(oldConfig.getStretching())
.uiConfig(oldConfig.getUiConfig())
.playlistUrl(playlistUrl)
.allowCrossProtocolRedirects(oldConfig.getAllowCrossProtocolRedirects())
.preload(oldConfig.getPreload())
.useTextureView(oldConfig.useTextureView())
.thumbnailPreview(oldConfig.getThumbnailPreview())
.mute(oldConfig.getMute())
.build();

player.setup(config);
}
}
});
} catch (IllegalViewOperationException e) {
throw e;
}
}

@ReactMethod
public void play(final int reactTag) {
try {
Expand Down
33 changes: 26 additions & 7 deletions android/src/main/java/com/jwplayer/rnjwplayer/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,30 @@

import static androidx.media3.common.util.Util.toByteArray;

import android.util.Log;
import android.util.Patterns;
import android.webkit.URLUtil;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.jwplayer.pub.api.JsonHelper;
import com.jwplayer.pub.api.media.ads.AdBreak;
import com.jwplayer.pub.api.media.captions.Caption;
import com.jwplayer.pub.api.media.captions.CaptionType;
import com.jwplayer.pub.api.media.playlists.MediaSource;
import com.jwplayer.pub.api.media.playlists.PlaylistItem;

import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Locale;
import java.util.Map;

public class Util {

Expand Down Expand Up @@ -62,7 +66,7 @@ public static byte[] executePost(String url, byte[] data, Map<String, String> re
}
}

public static boolean isValidURL(String url){
public static boolean isValidURL(String url) {
return URLUtil.isValidUrl(url) && Patterns.WEB_URL.matcher(url).matches();
}

Expand All @@ -75,14 +79,28 @@ public static List<PlaylistItem> createPlaylist(ReadableArray playlistItems) {
while (playlistItems.size() > j) {
ReadableMap playlistItem = playlistItems.getMap(j);

PlaylistItem newPlayListItem = getPlaylistItem((playlistItem));
playlist.add(newPlayListItem);
JSONObject obj;
PlaylistItem item = null;
// Try since legacy config may or may not conform to this standard
try {
obj = MapUtil.toJSONObject(playlistItem);
item = JsonHelper.parsePlaylistItemJson(obj);
} catch (Exception ex) {
Log.e("createPlaylist", ex.toString());
}
if (item != null) {
playlist.add(item);
} else {
// Try to use the legacy format
PlaylistItem newPlayListItem = getPlaylistItem((playlistItem));
playlist.add(newPlayListItem);
}
j++;
}
return playlist;
}

public static PlaylistItem getPlaylistItem (ReadableMap playlistItem) {
public static PlaylistItem getPlaylistItem(ReadableMap playlistItem) {
PlaylistItem.Builder itemBuilder = new PlaylistItem.Builder();

if (playlistItem.hasKey("file")) {
Expand Down Expand Up @@ -194,11 +212,12 @@ public static PlaylistItem getPlaylistItem (ReadableMap playlistItem) {

/**
* Internal helper for parsing a caption type from a known string
*
* @param type one of "CAPTIONS", "CHAPTERS", "THUMBNAILS"
* @return the correct Enum CaptionType
*/
public static CaptionType getCaptionType(String type){
for (CaptionType captionType: CaptionType.values()) {
public static CaptionType getCaptionType(String type) {
for (CaptionType captionType : CaptionType.values()) {
if (captionType.name().equals(type)) {
return CaptionType.valueOf(type);
}
Expand Down
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ declare module "@jwplayer/jwplayer-react-native" {
setControls(show: boolean): void;
setLockScreenControls(show: boolean): void;
seekTo(time: number): void;
loadPlaylist(playlistItems: PlaylistItem[]): void;
loadPlaylist(playlistItems: PlaylistItem[] | JwPlaylistItem[] | string): void;
setFullscreen(fullScreen: boolean): void;
position(): Promise<number>;
setUpCastController(): void;
Expand Down
2 changes: 2 additions & 0 deletions ios/RNJWPlayer/RNJWPlayerViewManager.m
edougher marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ @interface RCT_EXTERN_MODULE(RNJWPlayerViewManager, RCTViewManager)

RCT_EXTERN_METHOD(loadPlaylist: (nonnull NSNumber *)reactTag: (nonnull NSArray *)playlist)

RCT_EXTERN_METHOD(loadPlaylist: (nonnull NSNumber *)reactTag: (nonnull NSString *)playlist)

RCT_EXTERN_METHOD(setFullscreen: (nonnull NSNumber *)reactTag: (BOOL)fullscreen)

@end
31 changes: 21 additions & 10 deletions ios/RNJWPlayer/RNJWPlayerViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ class RNJWPlayerViewManager: RCTViewManager {
}
}

@objc func loadPlaylist(_ reactTag: NSNumber, _ playlist: [Any]) {
@objc func loadPlaylist(_ reactTag: NSNumber, _ playlist: Any) {
self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
guard let view = viewRegistry?[reactTag] as? RNJWPlayerView else {
print("Invalid view returned from registry, expecting RNJWPlayerView, got: \(String(describing: viewRegistry?[reactTag]))")
Expand All @@ -466,17 +466,28 @@ class RNJWPlayerViewManager: RCTViewManager {

var playlistArray = [JWPlayerItem]()

for item in playlist {
if let playerItem = try? view.getPlayerItem(item: item as! [String: Any]) {
playlistArray.append(playerItem)
if playlist is NSArray {
for item in playlist as! [Any] {
// TODO Update this to better parse JWP Playlist Items:
// awaiting JWP SDK exposure of JWJSONParser.playlist
if let playerItem = try? view.getPlayerItem(item: item as! [String: Any]) {
playlistArray.append(playerItem)
}
}

if let playerView = view.playerView {
playerView.player.loadPlaylist(items: playlistArray)
} else if let playerViewController = view.playerViewController {
playerViewController.player.loadPlaylist(items: playlistArray)
}
} else {
if let playerView = view.playerView {
playerView.player.loadPlaylist(url: URL(string: playlist as! String)!)
} else if let playerViewController = view.playerViewController {
playerViewController.player.loadPlaylist(url: URL(string: playlist as! String)!)
}
}

if let playerView = view.playerView {
playerView.player.loadPlaylist(items: playlistArray)
} else if let playerViewController = view.playerViewController {
playerViewController.player.loadPlaylist(items: playlistArray)
}

}
}

Expand Down