Skip to content

Commit

Permalink
[Improvement] Modernize loadPlaylist function with types and logic (#98)
Browse files Browse the repository at this point in the history
* Android - modernize loadPlaylist method with new types

* Add todo for iOS

* Allow for handling of playlist url in loadplaylist for iOS
  • Loading branch information
Jmilham21 authored Nov 15, 2024
1 parent 62c8df0 commit cb002b7
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 18 deletions.
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 @@ -586,7 +586,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
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,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 @@ -480,7 +480,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 @@ -489,17 +489,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

0 comments on commit cb002b7

Please sign in to comment.