diff --git a/TPStreamsRNPlayerView.podspec b/TPStreamsRNPlayerView.podspec index 03cd388..667318c 100644 --- a/TPStreamsRNPlayerView.podspec +++ b/TPStreamsRNPlayerView.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| 'DEFINES_MODULE' => 'YES', 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES' } - s.dependency "TPStreamsSDK" , "1.2.16" + s.dependency "TPStreamsSDK" , "1.2.23" # Ensure the module is not built as a framework to avoid bridging header conflicts diff --git a/android/gradle.properties b/android/gradle.properties index 1da033e..bf0bdf4 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -3,4 +3,4 @@ Tpstreams_minSdkVersion=24 Tpstreams_targetSdkVersion=34 Tpstreams_compileSdkVersion=35 Tpstreams_ndkVersion=27.1.12297006 -Tpstreams_tpstreamsAndroidPlayerVersion=1.1.8 \ No newline at end of file +Tpstreams_tpstreamsAndroidPlayerVersion=1.1.9 \ No newline at end of file diff --git a/android/src/main/java/com/tpstreams/JsonUtils.kt b/android/src/main/java/com/tpstreams/JsonUtils.kt index 5900a75..d9af2b3 100644 --- a/android/src/main/java/com/tpstreams/JsonUtils.kt +++ b/android/src/main/java/com/tpstreams/JsonUtils.kt @@ -1,5 +1,6 @@ package com.tpstreams +import org.json.JSONException import org.json.JSONObject object JsonUtils { @@ -43,4 +44,16 @@ object JsonUtils { } return map } -} \ No newline at end of file + + fun jsonStringToMap(jsonString: String?): Map? { + if (jsonString.isNullOrEmpty()) return null + return try { + val jsonObject = JSONObject(jsonString) + jsonObject.keys() + .asSequence() + .associate { it to jsonObject.getString(it) } + } catch (e: JSONException) { + null + } + } +} \ No newline at end of file diff --git a/android/src/main/java/com/tpstreams/TPStreamsDownloadModule.kt b/android/src/main/java/com/tpstreams/TPStreamsDownloadModule.kt index e4e0605..f8f430a 100644 --- a/android/src/main/java/com/tpstreams/TPStreamsDownloadModule.kt +++ b/android/src/main/java/com/tpstreams/TPStreamsDownloadModule.kt @@ -6,6 +6,7 @@ import com.facebook.react.bridge.Arguments import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule +import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.WritableMap import com.facebook.react.modules.core.DeviceEventManagerModule import com.tpstreams.player.download.DownloadClient @@ -23,6 +24,37 @@ class TPStreamsDownloadModule(private val reactContext: ReactApplicationContext) return "TPStreamsDownload" } + @ReactMethod + fun startDownload( + videoId: String, + accessToken: String, + resolution: String?, + metadata: ReadableMap?, + promise: Promise + ) { + try { + val metadataString = metadata?.let { org.json.JSONObject(it.toHashMap()).toString() } + val metadataMap = JsonUtils.jsonStringToMap(metadataString) + + val activity = currentActivity ?: run { + promise.reject("DOWNLOAD_START_ERROR", "No current activity available") + return + } + + downloadClient.startDownload( + activity, + videoId, + accessToken, + resolution, + metadataMap + ) + promise.resolve(null) + } catch (e: Exception) { + Log.e(TAG, "Error starting download: ${e.message}", e) + promise.reject("DOWNLOAD_START_ERROR", e.message, e) + } + } + @ReactMethod fun addDownloadProgressListener(promise: Promise) { try { diff --git a/android/src/main/java/com/tpstreams/TPStreamsRNPlayerViewManager.kt b/android/src/main/java/com/tpstreams/TPStreamsRNPlayerViewManager.kt index f1eb581..4bfe351 100644 --- a/android/src/main/java/com/tpstreams/TPStreamsRNPlayerViewManager.kt +++ b/android/src/main/java/com/tpstreams/TPStreamsRNPlayerViewManager.kt @@ -96,20 +96,7 @@ class TPStreamsRNPlayerViewManager : SimpleViewManager(), @ReactProp(name = "downloadMetadata") override fun setDownloadMetadata(view: TPStreamsRNPlayerView, metadata: String?) { - val metadataMap = if (!metadata.isNullOrEmpty()) { - try { - val jsonObject = org.json.JSONObject(metadata) - val map = jsonObject.keys() - .asSequence() - .associate { it to jsonObject.getString(it) } - .toMutableMap() - map - } catch (e: org.json.JSONException) { - android.util.Log.w("TPStreamsRN", "Error parsing download metadata: ${e.message}") - null - } - } else null - view.setDownloadMetadata(metadataMap) + view.setDownloadMetadata(JsonUtils.jsonStringToMap(metadata)) } // Command implementations diff --git a/ios/TPStreamsDownloadModule.mm b/ios/TPStreamsDownloadModule.mm index d324c36..5cccf81 100644 --- a/ios/TPStreamsDownloadModule.mm +++ b/ios/TPStreamsDownloadModule.mm @@ -11,6 +11,13 @@ @interface RCT_EXTERN_MODULE(TPStreamsDownload, RCTEventEmitter) rejecter:(RCTPromiseRejectBlock)reject) // Download Control Methods +RCT_EXTERN_METHOD(startDownload:(NSString *)videoId + accessToken:(NSString *)accessToken + resolution:(NSString *)resolution + metadata:(NSDictionary *)metadata + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) + RCT_EXTERN_METHOD(pauseDownload:(NSString *)videoId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) diff --git a/ios/TPStreamsDownloadModule.swift b/ios/TPStreamsDownloadModule.swift index 31f34c4..b2688b9 100644 --- a/ios/TPStreamsDownloadModule.swift +++ b/ios/TPStreamsDownloadModule.swift @@ -49,6 +49,20 @@ class TPStreamsDownloadModule: RCTEventEmitter, TPStreamsDownloadDelegate { return true } + @objc + func startDownload(_ videoId: String, accessToken: String, resolution: String?, metadata: NSDictionary?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + + let metadataDict = metadata as? [String: Any] + let res = (resolution?.isEmpty ?? true) ? nil : resolution + let presentingVC = (res == nil) ? RCTPresentedViewController() : nil + + self.downloadManager.startDownload(assetID: videoId, accessToken: accessToken, resolution: res, allowResolutionFallback: true, metadata: metadataDict, presentingViewController: presentingVC, completion: nil) + resolve(nil) + } + } + @objc func addDownloadProgressListener(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { isListening = true diff --git a/src/TPStreamsDownload.tsx b/src/TPStreamsDownload.tsx index f339b64..1ba838e 100644 --- a/src/TPStreamsDownload.tsx +++ b/src/TPStreamsDownload.tsx @@ -31,6 +31,20 @@ export type DownloadStateChangeListener = ( const downloadEventEmitter = new NativeEventEmitter(TPStreamsDownload); +export function startDownload( + videoId: string, + accessToken: string, + resolution: string | null = null, + metadata: Record | null = null +): Promise { + return TPStreamsDownload.startDownload( + videoId, + accessToken, + resolution, + metadata + ); +} + export function addDownloadProgressListener(): Promise { return TPStreamsDownload.addDownloadProgressListener(); } diff --git a/src/index.tsx b/src/index.tsx index 1085da8..d1b76ac 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,6 +8,7 @@ export { default as TPStreamsPlayerView } from './TPStreamsPlayer'; export type { TPStreamsPlayerRef } from './TPStreamsPlayer'; export { + startDownload, pauseDownload, resumeDownload, removeDownload,