feat(android): add new apis to query device capabilities

getWidevineLevel => integer between 0 and 3
isCodecSupported(codec, width, height) => boolean
isHEVCSupported() => boolean
This commit is contained in:
olivier bouillet 2022-06-23 22:54:03 +02:00
parent 8234fade96
commit 3a4cb7f6d9
4 changed files with 176 additions and 2 deletions

66
API.md
View File

@ -344,6 +344,13 @@ var styles = StyleSheet.create({
|[restoreUserInterfaceForPictureInPictureStop](#restoreuserinterfaceforpictureinpicturestop)|iOS|
|[seek](#seek)|All|
### Static methods
| Name |Plateforms Support |
|--|--|
|[getWidevineLevel](#getWidevineLevel)|Android|
|[isCodecSupported](#isCodecSupported)|Android|
|[isHEVCSupported](#isHEVCSupported)|Android|
### Configurable props
@ -1333,8 +1340,67 @@ this.player.seek(120, 50); // Seek to 2 minutes with +/- 50 milliseconds accurac
Platforms: iOS
#### Static methods
### Video Decoding capabilities
A module embed in ReactNativeVideo allow to query device supported feature.
To use it include the module as following:
```javascript
import { VideoDecoderProperties } from '@ifs/react-native-video-enhanced'
```
Platforms: Android
#### getWidevineLevel
Indicates whether the widevine level supported by device.
Possible results:
- **0** - unable to determine widevine support (typically not supported)
- **1**, **2**, **3** - Widevine level supported
Platforms: Android
Example:
```
VideoDecoderProperties.getWidevineLevel().then((widevineLevel) => {
...
}
```
#### isCodecSupported
Indicates whether the provided codec is supported level supported by device.
parameters:
- **mimetype**: mime type of codec to query
- **width**, **height**: resolution to query
Possible results:
- **true** - codec supported
- **false** - codec is not supported
Example:
```
VideoDecoderProperties.isCodecSupported('video/avc', 1920, 1080).then(
...
}
```
Platforms: Android
#### isHEVCSupported
Helper which Indicates whether the provided HEVC/1920*1080 is supported level supported by device.
It uses isCodecSupported internally.
Example:
```
VideoDecoderProperties.isHEVCSupported().then((hevcSupported) => {
...
}
```
### iOS App Transport Security

View File

@ -14,7 +14,8 @@ const styles = StyleSheet.create({
},
});
export { TextTrackType, FilterType, DRMType };
const { VideoDecoderProperties } = NativeModules
export { TextTrackType, FilterType, DRMType, VideoDecoderProperties }
export default class Video extends Component {

View File

@ -25,7 +25,9 @@ public class ReactVideoPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();
return Collections.singletonList(
new VideoDecoderPropertiesModule(reactContext)
);
}
// Deprecated RN 0.47

View File

@ -0,0 +1,105 @@
package com.brentvatne.react;
import android.annotation.SuppressLint;
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) {
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 (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
MediaCodecList mRegularCodecs = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
MediaFormat format = MediaFormat.createVideoFormat(mimeType, width, height);
String codecName = mRegularCodecs.findDecoderForFormat(format);
if (codecName == null) {
p.resolve(false);
} else {
p.resolve(true);
}
} else {
p.resolve(false);
}
}
@ReactMethod
public void isHEVCSupported(Promise p) {
isCodecSupported("video/hevc", 1920, 1080, p);
}
public VideoDecoderPropertiesModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
}