-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #298 from bitmovin/bufferapi-namespace
Implement BufferAPI via `Player.buffer`
- Loading branch information
Showing
11 changed files
with
409 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
android/src/main/java/com/bitmovin/player/reactnative/BufferModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.bitmovin.player.reactnative | ||
|
||
import com.bitmovin.player.api.buffer.BufferLevel | ||
import com.bitmovin.player.api.media.MediaType | ||
import com.bitmovin.player.reactnative.converter.JsonConverter | ||
import com.facebook.react.bridge.* | ||
import com.facebook.react.module.annotations.ReactModule | ||
import com.facebook.react.uimanager.UIManagerModule | ||
|
||
private const val MODULE_NAME = "BufferModule" | ||
|
||
@ReactModule(name = MODULE_NAME) | ||
class BufferModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) { | ||
override fun getName() = MODULE_NAME | ||
|
||
/** | ||
* Gets the [BufferLevel] from the Player | ||
* @param nativeId Target player id. | ||
* @param type The [type of buffer][JsonConverter.toBufferType] to return the level for. | ||
* @param promise JS promise object. | ||
*/ | ||
@ReactMethod | ||
fun getLevel(nativeId: NativeId, type: String, promise: Promise) { | ||
uiManager()?.addUIBlock { _ -> | ||
val player = playerModule()?.getPlayer(nativeId) ?: return@addUIBlock | ||
val bufferType = JsonConverter.toBufferType(type) | ||
if (bufferType == null) { | ||
promise.reject("Error: ", "Invalid buffer type") | ||
return@addUIBlock | ||
} | ||
val bufferLevels = RNBufferLevels( | ||
player.buffer.getLevel(bufferType, MediaType.Audio), | ||
player.buffer.getLevel(bufferType, MediaType.Video), | ||
) | ||
JsonConverter.fromRNBufferLevels(bufferLevels).let { | ||
promise.resolve(it) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Sets the target buffer level for the chosen buffer type across all media types. | ||
* @param nativeId Target player id. | ||
* @param type The [type of buffer][JsonConverter.toBufferType] to set the target level for. | ||
* @param value The value to set. | ||
*/ | ||
@ReactMethod | ||
fun setTargetLevel(nativeId: NativeId, type: String, value: Double) { | ||
uiManager()?.addUIBlock { _ -> | ||
val player = playerModule()?.getPlayer(nativeId) ?: return@addUIBlock | ||
val bufferType = JsonConverter.toBufferType(type) ?: return@addUIBlock | ||
player.buffer.setTargetLevel(bufferType, value) | ||
} | ||
} | ||
|
||
/** | ||
* Helper function that gets the instantiated `UIManagerModule` from modules registry. | ||
*/ | ||
private fun uiManager(): UIManagerModule? = context.getNativeModule(UIManagerModule::class.java) | ||
|
||
/** | ||
* Helper function that gets the instantiated `PlayerModule` from modules registry. | ||
*/ | ||
private fun playerModule(): PlayerModule? = context.getNativeModule(PlayerModule::class.java) | ||
} | ||
|
||
/** | ||
* Representation of the React Native API `BufferLevels` object. | ||
* This is necessary as we need a unified representation of the different APIs from both Android and iOS. | ||
*/ | ||
data class RNBufferLevels(val audio: BufferLevel, val video: BufferLevel) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#import <React/RCTBridgeModule.h> | ||
|
||
@interface RCT_EXTERN_REMAP_MODULE(BufferModule, BufferModule, NSObject) | ||
|
||
RCT_EXTERN_METHOD(getLevel:(NSString *)nativeId type:(nonnull NSString *)type resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) | ||
RCT_EXTERN_METHOD(setTargetLevel:(NSString *)nativeId type:(nonnull NSString *)type value:(nonnull NSNumber *)value) | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import BitmovinPlayer | ||
|
||
@objc(BufferModule) | ||
public class BufferModule: NSObject, RCTBridgeModule { | ||
// swiftlint:disable:next implicitly_unwrapped_optional | ||
@objc public var bridge: RCTBridge! | ||
|
||
/// PlayerModule instance fetched from the bridge's registry | ||
@objc var playerModule: PlayerModule? { | ||
bridge.module(for: PlayerModule.self) as? PlayerModule | ||
} | ||
|
||
// swiftlint:disable:next implicitly_unwrapped_optional | ||
public static func moduleName() -> String! { | ||
"BufferModule" | ||
} | ||
|
||
/// Module requires main thread initialization. | ||
public static func requiresMainQueueSetup() -> Bool { | ||
true | ||
} | ||
|
||
// swiftlint:disable:next implicitly_unwrapped_optional | ||
public var methodQueue: DispatchQueue! { | ||
bridge.uiManager.methodQueue | ||
} | ||
|
||
/** | ||
- Gets the `BufferLevel` from the Player | ||
- Parameter nativeId: Native Id of the the player instance. | ||
- Parameter type: The type of buffer to return the level for. | ||
- Parameter resolver: JS promise resolver. | ||
- Parameter rejecter: JS promise rejecter. | ||
*/ | ||
@objc(getLevel:type:resolver:rejecter:) | ||
func getLevel( | ||
_ playerId: NativeId, | ||
type: String, | ||
resolver resolve: @escaping RCTPromiseResolveBlock, | ||
rejecter reject: @escaping RCTPromiseRejectBlock | ||
) { | ||
bridge.uiManager.addUIBlock { [weak self] _, _ in | ||
guard let bufferApi = self?.playerModule?.retrieve(playerId)?.buffer else { | ||
reject("[BufferModule]", "Could not find player with ID (\(playerId))", nil) | ||
return | ||
} | ||
guard let bufferType = RCTConvert.bufferType(type) else { | ||
reject("[BufferModule]", "Invalid buffer type: (\(type))", nil) | ||
return | ||
} | ||
let level = bufferApi.getLevel(bufferType) | ||
let bufferLevels = RNBufferLevels(audio: level, video: level) | ||
resolve(RCTConvert.toJson(bufferLevels: bufferLevels)) | ||
} | ||
} | ||
|
||
/** | ||
* Sets the target level in seconds for the forward buffer. | ||
- Parameter nativeId: Target player id. | ||
- Parameter type: The type of the buffer to set the target level for. | ||
- Parameter value: The value to set. | ||
*/ | ||
@objc(setTargetLevel:type:value:) | ||
func setTargetLevel(_ playerId: NativeId, type: String, value: NSNumber) { | ||
let targetLevel = value.doubleValue | ||
bridge.uiManager.addUIBlock { [weak self] _, _ in | ||
let bufferType = RCTConvert.bufferType(type) | ||
guard | ||
bufferType == .forwardDuration, | ||
let bufferApi = self?.playerModule?.retrieve(playerId)?.buffer | ||
else { | ||
return | ||
} | ||
|
||
bufferApi.setTargetLevel(targetLevel) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.