refactor(android): migrate VideoDecoderPropertiesModule to Kotlin (#3954)

This commit is contained in:
YangJH 2024-07-01 00:32:30 +09:00 committed by GitHub
parent e5a2ee3bd3
commit 99585987ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 72 additions and 126 deletions

View File

@ -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;
}
}

View File

@ -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"
}
}