refactor(android): migrate VideoDecoderPropertiesModule to Kotlin (#3954)
This commit is contained in:
parent
e5a2ee3bd3
commit
99585987ea
@ -1,126 +0,0 @@
|
|||||||
package com.brentvatne.react;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.media.MediaCodecInfo;
|
|
||||||
import android.media.MediaCodecList;
|
|
||||||
import android.media.MediaDrm;
|
|
||||||
import android.media.MediaFormat;
|
|
||||||
import android.media.UnsupportedSchemeException;
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
|
|
||||||
import com.facebook.react.bridge.Promise;
|
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
|
|
||||||
public class VideoDecoderPropertiesModule extends ReactContextBaseJavaModule {
|
|
||||||
|
|
||||||
ReactApplicationContext reactContext;
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "VideoDecoderProperties";
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ObsoleteSdkInt")
|
|
||||||
@ReactMethod
|
|
||||||
public void getWidevineLevel(Promise p) {
|
|
||||||
int widevineLevel = 0;
|
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
|
||||||
p.resolve(widevineLevel);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final UUID WIDEVINE_UUID = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL);
|
|
||||||
final String WIDEVINE_SECURITY_LEVEL_1 = "L1";
|
|
||||||
final String WIDEVINE_SECURITY_LEVEL_2 = "L2";
|
|
||||||
final String WIDEVINE_SECURITY_LEVEL_3 = "L3";
|
|
||||||
final String SECURITY_LEVEL_PROPERTY = "securityLevel";
|
|
||||||
|
|
||||||
String securityProperty = null;
|
|
||||||
try {
|
|
||||||
MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
|
|
||||||
securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
|
|
||||||
} catch (UnsupportedSchemeException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if (securityProperty == null) {
|
|
||||||
p.resolve(widevineLevel);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (securityProperty) {
|
|
||||||
case WIDEVINE_SECURITY_LEVEL_1: {
|
|
||||||
widevineLevel = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WIDEVINE_SECURITY_LEVEL_2: {
|
|
||||||
widevineLevel = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WIDEVINE_SECURITY_LEVEL_3: {
|
|
||||||
widevineLevel = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
// widevineLevel 0
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.resolve(widevineLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ObsoleteSdkInt")
|
|
||||||
@ReactMethod
|
|
||||||
public void isCodecSupported(String mimeType, int width, int height, Promise p) {
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
p.resolve("unsupported");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaCodecList mRegularCodecs = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
|
|
||||||
MediaFormat format = MediaFormat.createVideoFormat(mimeType, width, height);
|
|
||||||
String codecName = mRegularCodecs.findDecoderForFormat(format);
|
|
||||||
|
|
||||||
if (codecName == null) {
|
|
||||||
p.resolve("unsupported");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback for android < 10
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
|
||||||
p.resolve("software");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isHardwareAccelerated = false;
|
|
||||||
|
|
||||||
for (MediaCodecInfo codecInfo : mRegularCodecs.getCodecInfos()) {
|
|
||||||
if (codecInfo.getName().equalsIgnoreCase(codecName)) {
|
|
||||||
isHardwareAccelerated = codecInfo.isHardwareAccelerated();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.resolve(isHardwareAccelerated ? "software" : "hardware");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ReactMethod
|
|
||||||
public void isHEVCSupported(Promise p) {
|
|
||||||
isCodecSupported("video/hevc", 1920, 1080, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VideoDecoderPropertiesModule(ReactApplicationContext reactContext) {
|
|
||||||
super(reactContext);
|
|
||||||
this.reactContext = reactContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.brentvatne.react
|
||||||
|
|
||||||
|
import android.media.MediaCodecList
|
||||||
|
import android.media.MediaDrm
|
||||||
|
import android.media.MediaFormat
|
||||||
|
import android.media.UnsupportedSchemeException
|
||||||
|
import android.os.Build
|
||||||
|
import com.facebook.react.bridge.Promise
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext
|
||||||
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
||||||
|
import com.facebook.react.bridge.ReactMethod
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
class VideoDecoderPropertiesModule(reactContext: ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) {
|
||||||
|
override fun getName(): String = REACT_CLASS
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun getWidevineLevel(p: Promise) {
|
||||||
|
var widevineLevel = 0
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||||
|
p.resolve(widevineLevel)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val mediaDrm = MediaDrm(WIDEVINE_UUID)
|
||||||
|
val securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY)
|
||||||
|
widevineLevel = when (securityProperty) {
|
||||||
|
"L1" -> 1
|
||||||
|
"L2" -> 2
|
||||||
|
"L3" -> 3
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
} catch (e: UnsupportedSchemeException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
p.resolve(widevineLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun isCodecSupported(mimeType: String?, width: Int, height: Int, p: Promise) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
p.resolve("unsupported")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val mRegularCodecs = MediaCodecList(MediaCodecList.REGULAR_CODECS)
|
||||||
|
val format = MediaFormat.createVideoFormat(mimeType!!, width, height)
|
||||||
|
val codecName = mRegularCodecs.findDecoderForFormat(format)
|
||||||
|
if (codecName == null) {
|
||||||
|
p.resolve("unsupported")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback for android < 10
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
p.resolve("software")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val isHardwareAccelerated = mRegularCodecs.codecInfos.any {
|
||||||
|
it.name.equals(codecName, ignoreCase = true) && it.isHardwareAccelerated
|
||||||
|
}
|
||||||
|
p.resolve(if (isHardwareAccelerated) "software" else "hardware")
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun isHEVCSupported(p: Promise) = isCodecSupported("video/hevc", 1920, 1080, p)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
|
||||||
|
private const val SECURITY_LEVEL_PROPERTY = "securityLevel"
|
||||||
|
private const val REACT_CLASS = "VideoManager"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user