Merge pull request #294 from tanersener/development-react-native

merge react native v4.5.1 changes to main
This commit is contained in:
Taner Şener 2022-01-02 15:05:29 +00:00 committed by GitHub
commit 873ab9dc48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1326 additions and 400 deletions

View File

@ -8,11 +8,11 @@
- `arm-v7a`, `arm-v7a-neon`, `arm64-v8a`, `x86` and `x86_64` architectures on Android
- `Android API Level 16` or later
- `armv7`, `armv7s`, `arm64`, `arm64-simulator`, `i386`, `x86_64`, `x86_64-mac-catalyst` and `arm64-mac-catalyst` architectures on iOS
- `iOS SDK 9.3` or later
- `iOS SDK 10` or later
- Can process Storage Access Framework (SAF) Uris on Android
- 24 external libraries
- 25 external libraries
`dav1d`, `fontconfig`, `freetype`, `fribidi`, `gmp`, `gnutls`, `kvazaar`, `lame`, `libass`, `libiconv`, `libilbc`, `libtheora`, `libvorbis`, `libvpx`, `libwebp`, `libxml2`, `opencore-amr`, `opus`, `shine`, `snappy`, `soxr`, `speex`, `twolame`, `vo-amrwbenc`
`dav1d`, `fontconfig`, `freetype`, `fribidi`, `gmp`, `gnutls`, `kvazaar`, `lame`, `libass`, `libiconv`, `libilbc`, `libtheora`, `libvorbis`, `libvpx`, `libwebp`, `libxml2`, `opencore-amr`, `opus`, `shine`, `snappy`, `soxr`, `speex`, `twolame`, `vo-amrwbenc`, `zimg`
- 4 external libraries with GPL license
@ -73,7 +73,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">min-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">min-gpl</td>
@ -82,7 +82,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">min-gpl-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">https</td>
@ -91,7 +91,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">https-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">https-gpl</td>
@ -100,7 +100,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">https-gpl-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">audio</td>
@ -109,7 +109,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">audio-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">video</td>
@ -118,7 +118,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">video-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">full</td>
@ -127,7 +127,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">full-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">full-gpl</td>
@ -136,7 +136,7 @@ The following table shows all package names and their respective API levels, iOS
<td align="center">12.1</td>
<td align="center">full-gpl-lts</td>
<td align="center">16</td>
<td align="center">9.3</td>
<td align="center">10</td>
</tr>
</tbody>
</table>
@ -152,7 +152,7 @@ packages using the instructions below.
- Edit `android/build.gradle` file and add the package name in `ext.ffmpegKitPackage` variable.
```
```gradle
ext {
ffmpegKitPackage = "<package name>"
}
@ -163,7 +163,7 @@ packages using the instructions below.
- Edit `ios/Podfile` file and add the package name as `subspec`. After that run `pod install` again.
```
```ruby
pod 'ffmpeg-kit-react-native', :subspecs => ['<package name>'], :podspec => '../node_modules/ffmpeg-kit-react-native/ffmpeg-kit-react-native.podspec'
```
@ -196,7 +196,7 @@ compare to each other.
```js
import { FFmpegKit } from 'ffmpeg-kit-react-native';
FFmpegKit.executeAsync('-i file1.mp4 -c:v mpeg4 file2.mp4', async (session) => {
FFmpegKit.execute('-i file1.mp4 -c:v mpeg4 file2.mp4').then(async (session) => {
const returnCode = await session.getReturnCode();
if (ReturnCode.isSuccess(returnCode)) {
@ -219,7 +219,7 @@ compare to each other.
session created.
```js
FFmpegKit.executeAsync('-i file1.mp4 -c:v mpeg4 file2.mp4').then(async (session) => {
FFmpegKit.execute('-i file1.mp4 -c:v mpeg4 file2.mp4').then(async (session) => {
// Unique session id created for this execution
const sessionId = session.getSessionId();
@ -276,7 +276,7 @@ compare to each other.
4. Execute `FFprobe` commands.
```js
FFprobeKit.executeAsync(ffprobeCommand, session => {
FFprobeKit.execute(ffprobeCommand).then(async (session) => {
// CALLED WHEN SESSION IS EXECUTED
@ -286,8 +286,18 @@ compare to each other.
5. Get media information for a file/url.
```js
FFprobeKit.getMediaInformationAsync('<file path or url>', async (session) => {
FFprobeKit.getMediaInformation(testUrl).then(async (session) => {
const information = await session.getMediaInformation();
if (information === undefined) {
// CHECK THE FOLLOWING ATTRIBUTES ON ERROR
const state = FFmpegKitConfig.sessionStateToString(await session.getState());
const returnCode = await session.getReturnCode();
const failStackTrace = await session.getFailStackTrace();
const duration = await session.getDuration();
const output = await session.getOutput();
}
});
```
@ -323,7 +333,7 @@ compare to each other.
});
```
8. Get previous `FFmpeg` and `FFprobe` sessions from the session history.
8. Get previous `FFmpeg`, `FFprobe` and `MediaInformation` sessions from the session history.
```js
FFmpegKit.listSessions().then(sessionList => {
@ -332,7 +342,13 @@ compare to each other.
});
});
FFprobeKit.listSessions().then(sessionList => {
FFprobeKit.listFFprobeSessions().then(sessionList => {
sessionList.forEach(async session => {
const sessionId = session.getSessionId();
});
});
FFprobeKit.listMediaInformationSessions().then(sessionList => {
sessionList.forEach(async session => {
const sessionId = session.getSessionId();
});
@ -340,10 +356,18 @@ compare to each other.
```
9. Enable global callbacks.
- Execute Callback, called when an async execution is ended
- Session type specific Complete Callbacks, called when an async session has been completed
```js
FFmpegKitConfig.enableExecuteCallback(session => {
FFmpegKitConfig.enableFFmpegSessionCompleteCallback(session => {
const sessionId = session.getSessionId();
});
FFmpegKitConfig.enableFFprobeSessionCompleteCallback(session => {
const sessionId = session.getSessionId();
});
FFmpegKitConfig.enableMediaInformationSessionCompleteCallback(session => {
const sessionId = session.getSessionId();
});
```

View File

@ -31,8 +31,8 @@ android {
defaultConfig {
minSdkVersion safeExtGet('ffmpegKitPackage', 'https').contains("-lts") ? 16 : 24
targetSdkVersion 30
versionCode 450
versionName "4.5.0"
versionCode 451
versionName "4.5.1"
}
buildTypes {

View File

@ -1,3 +1,3 @@
android.useAndroidX=true
ffmpegKit.android.main.version=4.5
ffmpegKit.android.lts.version=4.5
ffmpegKit.android.main.version=4.5.1-1
ffmpegKit.android.lts.version=4.5.1-1

View File

@ -74,7 +74,6 @@ import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule implements LifecycleEventListener {
@ -112,7 +111,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
// EVENTS
public static final String EVENT_LOG_CALLBACK_EVENT = "FFmpegKitLogCallbackEvent";
public static final String EVENT_STATISTICS_CALLBACK_EVENT = "FFmpegKitStatisticsCallbackEvent";
public static final String EVENT_EXECUTE_CALLBACK_EVENT = "FFmpegKitExecuteCallbackEvent";
public static final String EVENT_COMPLETE_CALLBACK_EVENT = "FFmpegKitCompleteCallbackEvent";
// REQUEST CODES
public static final int READABLE_REQUEST_CODE = 10000;
@ -122,14 +121,14 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
private final AtomicBoolean logsEnabled;
private final AtomicBoolean statisticsEnabled;
private final ExecutorService asyncWriteToPipeExecutorService;
private final ExecutorService asyncExecutorService;
public FFmpegKitReactNativeModule(@Nullable ReactApplicationContext reactContext) {
super(reactContext);
this.logsEnabled = new AtomicBoolean(false);
this.statisticsEnabled = new AtomicBoolean(false);
this.asyncWriteToPipeExecutorService = Executors.newFixedThreadPool(asyncWriteToPipeConcurrencyLimit);
this.asyncExecutorService = Executors.newFixedThreadPool(asyncWriteToPipeConcurrencyLimit);
if (reactContext != null) {
reactContext.addLifecycleEventListener(this);
@ -162,13 +161,23 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
@Override
public void onHostDestroy() {
this.asyncWriteToPipeExecutorService.shutdown();
this.asyncExecutorService.shutdown();
}
protected void registerGlobalCallbacks(final ReactApplicationContext reactContext) {
FFmpegKitConfig.enableExecuteCallback(session -> {
FFmpegKitConfig.enableFFmpegSessionCompleteCallback(session -> {
final DeviceEventManagerModule.RCTDeviceEventEmitter jsModule = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
jsModule.emit(EVENT_EXECUTE_CALLBACK_EVENT, toMap(session));
jsModule.emit(EVENT_COMPLETE_CALLBACK_EVENT, toMap(session));
});
FFmpegKitConfig.enableFFprobeSessionCompleteCallback(session -> {
final DeviceEventManagerModule.RCTDeviceEventEmitter jsModule = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
jsModule.emit(EVENT_COMPLETE_CALLBACK_EVENT, toMap(session));
});
FFmpegKitConfig.enableMediaInformationSessionCompleteCallback(session -> {
final DeviceEventManagerModule.RCTDeviceEventEmitter jsModule = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
jsModule.emit(EVENT_COMPLETE_CALLBACK_EVENT, toMap(session));
});
FFmpegKitConfig.enableLogCallback(log -> {
@ -235,7 +244,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
timeout = AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT;
}
final List<com.arthenica.ffmpegkit.Log> allLogs = session.getAllLogs(timeout);
promise.resolve(toArray(allLogs.stream().map(FFmpegKitReactNativeModule::toMap)));
promise.resolve(toLogArray(allLogs));
}
} else {
promise.reject("INVALID_SESSION", "Invalid session id.");
@ -250,7 +259,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
final List<com.arthenica.ffmpegkit.Log> allLogs = session.getLogs();
promise.resolve(toArray(allLogs.stream().map(FFmpegKitReactNativeModule::toMap)));
promise.resolve(toLogArray(allLogs));
}
} else {
promise.reject("INVALID_SESSION", "Invalid session id.");
@ -360,7 +369,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFmpegSession) {
if (session.isFFmpeg()) {
final int timeout;
if (isValidPositiveNumber(waitTimeout)) {
timeout = waitTimeout.intValue();
@ -368,7 +377,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
timeout = AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT;
}
final List<Statistics> allStatistics = ((FFmpegSession) session).getAllStatistics(timeout);
promise.resolve(toArray(allStatistics.stream().map(FFmpegKitReactNativeModule::toMap)));
promise.resolve(toStatisticsArray(allStatistics));
} else {
promise.reject("NOT_FFMPEG_SESSION", "A session is found but it does not have the correct type.");
}
@ -385,9 +394,9 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFmpegSession) {
if (session.isFFmpeg()) {
final List<Statistics> statistics = ((FFmpegSession) session).getStatistics();
promise.resolve(toArray(statistics.stream().map(FFmpegKitReactNativeModule::toMap)));
promise.resolve(toStatisticsArray(statistics));
} else {
promise.reject("NOT_FFMPEG_SESSION", "A session is found but it does not have the correct type.");
}
@ -574,6 +583,69 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
}
}
@ReactMethod
public void ffmpegSessionExecute(final Double sessionId, final Promise promise) {
if (sessionId != null) {
Session session = FFmpegKitConfig.getSession(sessionId.longValue());
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session.isFFmpeg()) {
final FFmpegSessionExecuteTask ffmpegSessionExecuteTask = new FFmpegSessionExecuteTask((FFmpegSession) session, promise);
asyncExecutorService.submit(ffmpegSessionExecuteTask);
} else {
promise.reject("NOT_FFMPEG_SESSION", "A session is found but it does not have the correct type.");
}
}
} else {
promise.reject("INVALID_SESSION", "Invalid session id.");
}
}
@ReactMethod
public void ffprobeSessionExecute(final Double sessionId, final Promise promise) {
if (sessionId != null) {
Session session = FFmpegKitConfig.getSession(sessionId.longValue());
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session.isFFprobe()) {
final FFprobeSessionExecuteTask ffprobeSessionExecuteTask = new FFprobeSessionExecuteTask((FFprobeSession) session, promise);
asyncExecutorService.submit(ffprobeSessionExecuteTask);
} else {
promise.reject("NOT_FFPROBE_SESSION", "A session is found but it does not have the correct type.");
}
}
} else {
promise.reject("INVALID_SESSION", "Invalid session id.");
}
}
@ReactMethod
public void mediaInformationSessionExecute(final Double sessionId, final Double waitTimeout, final Promise promise) {
if (sessionId != null) {
Session session = FFmpegKitConfig.getSession(sessionId.longValue());
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session.isMediaInformation()) {
final int timeout;
if (isValidPositiveNumber(waitTimeout)) {
timeout = waitTimeout.intValue();
} else {
timeout = AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT;
}
final MediaInformationSessionExecuteTask mediaInformationSessionExecuteTask = new MediaInformationSessionExecuteTask((MediaInformationSession) session, timeout, promise);
asyncExecutorService.submit(mediaInformationSessionExecuteTask);
} else {
promise.reject("NOT_MEDIA_INFORMATION_SESSION", "A session is found but it does not have the correct type.");
}
}
} else {
promise.reject("INVALID_SESSION", "Invalid session id.");
}
}
@ReactMethod
public void asyncFFmpegSessionExecute(final Double sessionId, final Promise promise) {
if (sessionId != null) {
@ -581,7 +653,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFmpegSession) {
if (session.isFFmpeg()) {
FFmpegKitConfig.asyncFFmpegExecute((FFmpegSession) session);
promise.resolve(null);
} else {
@ -600,7 +672,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFprobeSession) {
if (session.isFFprobe()) {
FFmpegKitConfig.asyncFFprobeExecute((FFprobeSession) session);
promise.resolve(null);
} else {
@ -619,7 +691,7 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof MediaInformationSession) {
if (session.isMediaInformation()) {
final int timeout;
if (isValidPositiveNumber(waitTimeout)) {
timeout = waitTimeout.intValue();
@ -744,8 +816,8 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
@ReactMethod
public void writeToPipe(final String inputPath, final String namedPipePath, final Promise promise) {
final AsyncWriteToPipeTask asyncTask = new AsyncWriteToPipeTask(inputPath, namedPipePath, promise);
asyncWriteToPipeExecutorService.submit(asyncTask);
final WriteToPipeTask asyncTask = new WriteToPipeTask(inputPath, namedPipePath, promise);
asyncExecutorService.submit(asyncTask);
}
@ReactMethod
@ -822,22 +894,18 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
}
@ReactMethod
public void getSafParameter(final Boolean writable, final String uriString, final Promise promise) {
public void getSafParameter(final String uriString, final String openMode, final Promise promise) {
final ReactApplicationContext reactContext = getReactApplicationContext();
final Uri uri = Uri.parse(uriString);
if (uri == null) {
Log.w(LIBRARY_NAME, String.format("Cannot getSafParameter using parameters writable: %s, uriString: %s. Uri string cannot be parsed.", writable, uriString));
Log.w(LIBRARY_NAME, String.format("Cannot getSafParameter using parameters uriString: %s, openMode: %s. Uri string cannot be parsed.", uriString, openMode));
promise.reject("GET_SAF_PARAMETER_FAILED", "Uri string cannot be parsed.");
} else {
final String safParameter;
if (writable) {
safParameter = FFmpegKitConfig.getSafParameterForWrite(reactContext, uri);
} else {
safParameter = FFmpegKitConfig.getSafParameterForRead(reactContext, uri);
}
safParameter = FFmpegKitConfig.getSafParameter(reactContext, uri, openMode);
Log.d(LIBRARY_NAME, String.format("getSafParameter using parameters writable: %s, uriString: %s completed with saf parameter: %s.", writable, uriString, safParameter));
Log.d(LIBRARY_NAME, String.format("getSafParameter using parameters uriString: %s, openMode: %s completed with saf parameter: %s.", uriString, openMode, safParameter));
promise.resolve(safParameter);
}
@ -870,7 +938,38 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
@ReactMethod
public void getFFprobeSessions(final Promise promise) {
promise.resolve(toSessionArray(FFprobeKit.listSessions()));
promise.resolve(toSessionArray(FFprobeKit.listFFprobeSessions()));
}
@ReactMethod
public void getMediaInformationSessions(final Promise promise) {
promise.resolve(toSessionArray(FFprobeKit.listMediaInformationSessions()));
}
// MediaInformationSession
@ReactMethod
public void getMediaInformation(final Double sessionId, final Promise promise) {
if (sessionId != null) {
final Session session = FFmpegKitConfig.getSession(sessionId.longValue());
if (session == null) {
promise.reject("SESSION_NOT_FOUND", "Session not found.");
} else {
if (session.isMediaInformation()) {
final MediaInformationSession mediaInformationSession = (MediaInformationSession) session;
final MediaInformation mediaInformation = mediaInformationSession.getMediaInformation();
if (mediaInformation != null) {
promise.resolve(toMap(mediaInformation));
} else {
promise.resolve(null);
}
} else {
promise.reject("NOT_MEDIA_INFORMATION_SESSION", "A session is found but it does not have the correct type.");
}
}
} else {
promise.reject("INVALID_SESSION", "Invalid session id.");
}
}
// Packages
@ -917,19 +1016,17 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
sessionMap.putDouble(KEY_SESSION_START_TIME, toLong(session.getStartTime()));
sessionMap.putString(KEY_SESSION_COMMAND, session.getCommand());
if (session.isFFprobe()) {
if (session instanceof MediaInformationSession) {
final MediaInformationSession mediaInformationSession = (MediaInformationSession) session;
final MediaInformation mediaInformation = mediaInformationSession.getMediaInformation();
if (mediaInformation != null) {
sessionMap.putMap(KEY_SESSION_MEDIA_INFORMATION, toMap(mediaInformation));
}
sessionMap.putDouble(KEY_SESSION_TYPE, SESSION_TYPE_MEDIA_INFORMATION);
} else {
sessionMap.putDouble(KEY_SESSION_TYPE, SESSION_TYPE_FFPROBE);
}
} else {
if (session.isFFmpeg()) {
sessionMap.putDouble(KEY_SESSION_TYPE, SESSION_TYPE_FFMPEG);
} else if (session.isFFprobe()) {
sessionMap.putDouble(KEY_SESSION_TYPE, SESSION_TYPE_FFPROBE);
} else if (session.isMediaInformation()) {
final MediaInformationSession mediaInformationSession = (MediaInformationSession) session;
final MediaInformation mediaInformation = mediaInformationSession.getMediaInformation();
if (mediaInformation != null) {
sessionMap.putMap(KEY_SESSION_MEDIA_INFORMATION, toMap(mediaInformation));
}
sessionMap.putDouble(KEY_SESSION_TYPE, SESSION_TYPE_MEDIA_INFORMATION);
}
return sessionMap;
@ -1046,16 +1143,6 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
return statisticsMap;
}
protected static WritableArray toSessionArray(final List<? extends Session> sessions) {
final WritableArray sessionArray = Arguments.createArray();
for (int i = 0; i < sessions.size(); i++) {
sessionArray.pushMap(toMap(sessions.get(i)));
}
return sessionArray;
}
protected static WritableMap toMap(final MediaInformation mediaInformation) {
WritableMap map = Arguments.createMap();
@ -1102,14 +1189,6 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
return map;
}
protected static WritableArray toArray(final Stream<WritableMap> stream) {
final WritableArray list = Arguments.createArray();
stream.forEachOrdered(list::pushMap);
return list;
}
protected static WritableArray toList(final JSONArray array) {
final WritableArray list = Arguments.createArray();
@ -1152,6 +1231,36 @@ public class FFmpegKitReactNativeModule extends ReactContextBaseJavaModule imple
return arguments.toArray(new String[0]);
}
protected static WritableArray toSessionArray(final List<? extends Session> sessionList) {
final WritableArray sessionArray = Arguments.createArray();
for (int i = 0; i < sessionList.size(); i++) {
sessionArray.pushMap(toMap(sessionList.get(i)));
}
return sessionArray;
}
protected static WritableArray toLogArray(final List<com.arthenica.ffmpegkit.Log> logList) {
final WritableArray logArray = Arguments.createArray();
for (int i = 0; i < logList.size(); i++) {
logArray.pushMap(toMap(logList.get(i)));
}
return logArray;
}
protected static WritableArray toStatisticsArray(final List<com.arthenica.ffmpegkit.Statistics> statisticsList) {
final WritableArray statisticsArray = Arguments.createArray();
for (int i = 0; i < statisticsList.size(); i++) {
statisticsArray.pushMap(toMap(statisticsList.get(i)));
}
return statisticsArray;
}
protected static boolean isValidPositiveNumber(final Double value) {
return (value != null) && (value.intValue() >= 0);
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
package com.arthenica.ffmpegkit.reactnative;
import com.arthenica.ffmpegkit.FFmpegKitConfig;
import com.arthenica.ffmpegkit.FFmpegSession;
import com.facebook.react.bridge.Promise;
public class FFmpegSessionExecuteTask implements Runnable {
private final FFmpegSession ffmpegSession;
private final Promise promise;
public FFmpegSessionExecuteTask(final FFmpegSession ffmpegSession, final Promise promise) {
this.ffmpegSession = ffmpegSession;
this.promise = promise;
}
@Override
public void run() {
FFmpegKitConfig.ffmpegExecute(ffmpegSession);
promise.resolve(null);
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
package com.arthenica.ffmpegkit.reactnative;
import com.arthenica.ffmpegkit.FFmpegKitConfig;
import com.arthenica.ffmpegkit.FFprobeSession;
import com.facebook.react.bridge.Promise;
public class FFprobeSessionExecuteTask implements Runnable {
private final FFprobeSession ffprobeSession;
private final Promise promise;
public FFprobeSessionExecuteTask(final FFprobeSession ffprobeSession, final Promise promise) {
this.ffprobeSession = ffprobeSession;
this.promise = promise;
}
@Override
public void run() {
FFmpegKitConfig.ffprobeExecute(ffprobeSession);
promise.resolve(null);
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
package com.arthenica.ffmpegkit.reactnative;
import com.arthenica.ffmpegkit.FFmpegKitConfig;
import com.arthenica.ffmpegkit.MediaInformationSession;
import com.facebook.react.bridge.Promise;
public class MediaInformationSessionExecuteTask implements Runnable {
private final MediaInformationSession mediaInformationSession;
private final int timeout;
private final Promise promise;
public MediaInformationSessionExecuteTask(final MediaInformationSession mediaInformationSession, final int timeout, final Promise promise) {
this.mediaInformationSession = mediaInformationSession;
this.timeout = timeout;
this.promise = promise;
}
@Override
public void run() {
FFmpegKitConfig.getMediaInformationExecute(mediaInformationSession, timeout);
promise.resolve(null);
}
}

View File

@ -27,12 +27,12 @@ import com.facebook.react.bridge.Promise;
import java.io.IOException;
public class AsyncWriteToPipeTask implements Runnable {
public class WriteToPipeTask implements Runnable {
private final String inputPath;
private final String namedPipePath;
private final Promise promise;
public AsyncWriteToPipeTask(final String inputPath, final String namedPipePath, final Promise promise) {
public WriteToPipeTask(final String inputPath, final String namedPipePath, final Promise promise) {
this.inputPath = inputPath;
this.namedPipePath = namedPipePath;
this.promise = promise;

View File

@ -23,113 +23,113 @@ Pod::Spec.new do |s|
s.subspec 'min' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-min', "4.5"
ss.dependency 'ffmpeg-kit-ios-min', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'min-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-min', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-min', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
s.subspec 'min-gpl' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-min-gpl', "4.5"
ss.dependency 'ffmpeg-kit-ios-min-gpl', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'min-gpl-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-min-gpl', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-min-gpl', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
s.subspec 'https' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-https', "4.5"
ss.dependency 'ffmpeg-kit-ios-https', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'https-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-https', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-https', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
s.subspec 'https-gpl' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-https-gpl', "4.5"
ss.dependency 'ffmpeg-kit-ios-https-gpl', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'https-gpl-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-https-gpl', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-https-gpl', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
s.subspec 'audio' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-audio', "4.5"
ss.dependency 'ffmpeg-kit-ios-audio', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'audio-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-audio', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-audio', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
s.subspec 'video' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-video', "4.5"
ss.dependency 'ffmpeg-kit-ios-video', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'video-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-video', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-video', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
s.subspec 'full' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-full', "4.5"
ss.dependency 'ffmpeg-kit-ios-full', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'full-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-full', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-full', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
s.subspec 'full-gpl' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-full-gpl', "4.5"
ss.dependency 'ffmpeg-kit-ios-full-gpl', "4.5.1"
ss.ios.deployment_target = '12.1'
end
s.subspec 'full-gpl-lts' do |ss|
ss.source_files = '**/FFmpegKitReactNativeModule.m',
'**/FFmpegKitReactNativeModule.h'
ss.dependency 'ffmpeg-kit-ios-full-gpl', "4.5.LTS"
ss.ios.deployment_target = '9.3'
ss.dependency 'ffmpeg-kit-ios-full-gpl', "4.5.1.LTS"
ss.ios.deployment_target = '10'
end
end

View File

@ -61,14 +61,14 @@ static int const SESSION_TYPE_MEDIA_INFORMATION = 3;
// EVENTS
static NSString *const EVENT_LOG_CALLBACK_EVENT = @"FFmpegKitLogCallbackEvent";
static NSString *const EVENT_STATISTICS_CALLBACK_EVENT = @"FFmpegKitStatisticsCallbackEvent";
static NSString *const EVENT_EXECUTE_CALLBACK_EVENT = @"FFmpegKitExecuteCallbackEvent";
static NSString *const EVENT_COMPLETE_CALLBACK_EVENT = @"FFmpegKitCompleteCallbackEvent";
extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
@implementation FFmpegKitReactNativeModule {
BOOL logsEnabled;
BOOL statisticsEnabled;
dispatch_queue_t asyncWriteToPipeDispatchQueue;
dispatch_queue_t asyncDispatchQueue;
}
RCT_EXPORT_MODULE(FFmpegKitReactNativeModule);
@ -78,7 +78,7 @@ RCT_EXPORT_MODULE(FFmpegKitReactNativeModule);
if (self) {
logsEnabled = false;
statisticsEnabled = false;
asyncWriteToPipeDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
asyncDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[self registerGlobalCallbacks];
}
@ -91,15 +91,25 @@ RCT_EXPORT_MODULE(FFmpegKitReactNativeModule);
[array addObject:EVENT_LOG_CALLBACK_EVENT];
[array addObject:EVENT_STATISTICS_CALLBACK_EVENT];
[array addObject:EVENT_EXECUTE_CALLBACK_EVENT];
[array addObject:EVENT_COMPLETE_CALLBACK_EVENT];
return array;
}
- (void)registerGlobalCallbacks {
[FFmpegKitConfig enableExecuteCallback:^(id<Session> session){
[FFmpegKitConfig enableFFmpegSessionCompleteCallback:^(FFmpegSession* session){
NSDictionary *dictionary = [FFmpegKitReactNativeModule toSessionDictionary:session];
[self sendEventWithName:EVENT_EXECUTE_CALLBACK_EVENT body:dictionary];
[self sendEventWithName:EVENT_COMPLETE_CALLBACK_EVENT body:dictionary];
}];
[FFmpegKitConfig enableFFprobeSessionCompleteCallback:^(FFprobeSession* session){
NSDictionary *dictionary = [FFmpegKitReactNativeModule toSessionDictionary:session];
[self sendEventWithName:EVENT_COMPLETE_CALLBACK_EVENT body:dictionary];
}];
[FFmpegKitConfig enableMediaInformationSessionCompleteCallback:^(MediaInformationSession* session){
NSDictionary *dictionary = [FFmpegKitReactNativeModule toSessionDictionary:session];
[self sendEventWithName:EVENT_COMPLETE_CALLBACK_EVENT body:dictionary];
}];
[FFmpegKitConfig enableLogCallback: ^(Log* log){
@ -234,7 +244,7 @@ RCT_EXPORT_METHOD(getArch:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRe
// FFmpegSession
RCT_EXPORT_METHOD(ffmpegSession:(NSArray*)arguments resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withExecuteCallback:nil withLogCallback:nil withStatisticsCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withCompleteCallback:nil withLogCallback:nil withStatisticsCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
resolve([FFmpegKitReactNativeModule toSessionDictionary:session]);
}
@ -243,7 +253,7 @@ RCT_EXPORT_METHOD(ffmpegSessionGetAllStatistics:(int)sessionId withTimeout:(int)
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isMemberOfClass:[FFmpegSession class]]) {
if ([session isFFmpeg]) {
int timeout;
if ([FFmpegKitReactNativeModule isValidPositiveNumber:waitTimeout]) {
timeout = waitTimeout;
@ -263,7 +273,7 @@ RCT_EXPORT_METHOD(ffmpegSessionGetStatistics:(int)sessionId resolver:(RCTPromise
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isMemberOfClass:[FFmpegSession class]]) {
if ([session isFFmpeg]) {
NSArray* statistics = [(FFmpegSession*)session getStatistics];
resolve([FFmpegKitReactNativeModule toStatisticsArray:statistics]);
} else {
@ -275,14 +285,14 @@ RCT_EXPORT_METHOD(ffmpegSessionGetStatistics:(int)sessionId resolver:(RCTPromise
// FFprobeSession
RCT_EXPORT_METHOD(ffprobeSession:(NSArray*)arguments resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withExecuteCallback:nil withLogCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withCompleteCallback:nil withLogCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
resolve([FFmpegKitReactNativeModule toSessionDictionary:session]);
}
// MediaInformationSession
RCT_EXPORT_METHOD(mediaInformationSession:(NSArray*)arguments resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:nil withLogCallback:nil];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withCompleteCallback:nil withLogCallback:nil];
resolve([FFmpegKitReactNativeModule toSessionDictionary:session]);
}
@ -404,12 +414,65 @@ RCT_EXPORT_METHOD(ignoreSignal:(int)signalValue resolver:(RCTPromiseResolveBlock
}
}
RCT_EXPORT_METHOD(ffmpegSessionExecute:(int)sessionId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:sessionId];
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isFFmpeg]) {
dispatch_async(asyncDispatchQueue, ^{
[FFmpegKitConfig ffmpegExecute:(FFmpegSession*)session];
resolve(nil);
});
} else {
reject(@"NOT_FFMPEG_SESSION", @"A session is found but it does not have the correct type.", nil);
}
}
}
RCT_EXPORT_METHOD(ffprobeSessionExecute:(int)sessionId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:sessionId];
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isFFprobe]) {
dispatch_async(asyncDispatchQueue, ^{
[FFmpegKitConfig ffprobeExecute:(FFprobeSession*)session];
resolve(nil);
});
} else {
reject(@"NOT_FFPROBE_SESSION", @"A session is found but it does not have the correct type.", nil);
}
}
}
RCT_EXPORT_METHOD(mediaInformationSessionExecute:(int)sessionId withTimeout:(int)waitTimeout resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:sessionId];
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isMediaInformation]) {
int timeout;
if ([FFmpegKitReactNativeModule isValidPositiveNumber:waitTimeout]) {
timeout = waitTimeout;
} else {
timeout = AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
}
dispatch_async(asyncDispatchQueue, ^{
[FFmpegKitConfig getMediaInformationExecute:(MediaInformationSession*)session withTimeout:timeout];
resolve(nil);
});
} else {
reject(@"NOT_MEDIA_INFORMATION_SESSION", @"A session is found but it does not have the correct type.", nil);
}
}
}
RCT_EXPORT_METHOD(asyncFFmpegSessionExecute:(int)sessionId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:sessionId];
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isMemberOfClass:[FFmpegSession class]]) {
if ([session isFFmpeg]) {
[FFmpegKitConfig asyncFFmpegExecute:(FFmpegSession*)session];
resolve(nil);
} else {
@ -423,7 +486,7 @@ RCT_EXPORT_METHOD(asyncFFprobeSessionExecute:(int)sessionId resolver:(RCTPromise
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isMemberOfClass:[FFprobeSession class]]) {
if ([session isFFprobe]) {
[FFmpegKitConfig asyncFFprobeExecute:(FFprobeSession*)session];
resolve(nil);
} else {
@ -437,7 +500,7 @@ RCT_EXPORT_METHOD(asyncMediaInformationSessionExecute:(int)sessionId withTimeout
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isMemberOfClass:[MediaInformationSession class]]) {
if ([session isMediaInformation]) {
int timeout;
if ([FFmpegKitReactNativeModule isValidPositiveNumber:waitTimeout]) {
timeout = waitTimeout;
@ -518,7 +581,7 @@ RCT_EXPORT_METHOD(getPlatform:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromi
}
RCT_EXPORT_METHOD(writeToPipe:(NSString*)inputPath onPipe:(NSString*)namedPipePath resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
dispatch_async(asyncWriteToPipeDispatchQueue, ^{
dispatch_async(asyncDispatchQueue, ^{
NSLog(@"Starting copy %@ to pipe %@ operation.\n", inputPath, namedPipePath);
@ -574,7 +637,7 @@ RCT_EXPORT_METHOD(selectDocument:(BOOL)writable title:(NSString*)title type:(NSS
reject(@"Not Supported", @"Not supported on iOS platform.", nil);
}
RCT_EXPORT_METHOD(getSafParameter:(BOOL)writable uri:(NSString*)uriString resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(getSafParameter:(NSString*)uriString mode:(NSString*)openMode resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
reject(@"Not Supported", @"Not supported on iOS platform.", nil);
}
@ -599,7 +662,27 @@ RCT_EXPORT_METHOD(getFFmpegSessions:(RCTPromiseResolveBlock)resolve rejecter:(RC
// FFprobeKit
RCT_EXPORT_METHOD(getFFprobeSessions:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
resolve([FFmpegKitReactNativeModule toSessionArray:[FFprobeKit listSessions]]);
resolve([FFmpegKitReactNativeModule toSessionArray:[FFprobeKit listFFprobeSessions]]);
}
RCT_EXPORT_METHOD(getMediaInformationSessions:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
resolve([FFmpegKitReactNativeModule toSessionArray:[FFprobeKit listMediaInformationSessions]]);
}
// MediaInformationSession
RCT_EXPORT_METHOD(getMediaInformation:(int)sessionId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:sessionId];
if (session == nil) {
reject(@"SESSION_NOT_FOUND", @"Session not found.", nil);
} else {
if ([session isMediaInformation]) {
MediaInformationSession *mediaInformationSession = (MediaInformationSession*)session;
resolve([FFmpegKitReactNativeModule toMediaInformationDictionary:[mediaInformationSession getMediaInformation]]);
} else {
reject(@"NOT_MEDIA_INFORMATION_SESSION", @"A session is found but it does not have the correct type.", nil);
}
}
}
// Packages
@ -628,6 +711,10 @@ RCT_EXPORT_METHOD(getExternalLibraries:(RCTPromiseResolveBlock)resolve rejecter:
statisticsEnabled = false;
}
+ (BOOL)requiresMainQueueSetup {
return NO;
}
+ (NSDictionary*)toSessionDictionary:(id<Session>) session {
if (session != nil) {
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
@ -638,7 +725,7 @@ RCT_EXPORT_METHOD(getExternalLibraries:(RCTPromiseResolveBlock)resolve rejecter:
dictionary[KEY_SESSION_COMMAND] = [session getCommand];
if ([session isFFprobe]) {
if ([(AbstractSession*)session isMemberOfClass:[MediaInformationSession class]]) {
if ([session isMediaInformation]) {
MediaInformationSession *mediaInformationSession = (MediaInformationSession*)session;
dictionary[KEY_SESSION_MEDIA_INFORMATION] = [FFmpegKitReactNativeModule toMediaInformationDictionary:[mediaInformationSession getMediaInformation]];
dictionary[KEY_SESSION_TYPE] = [NSNumber numberWithInt:SESSION_TYPE_MEDIA_INFORMATION];

View File

@ -1,22 +1,11 @@
{
"name": "ffmpeg-kit-react-native",
"version": "4.5.0",
"version": "4.5.1",
"description": "FFmpeg Kit for React Native",
"main": "src/index",
"types": "src/index.d.ts",
"react-native": "src/index",
"source": "src/index",
"files": [
"android",
"ffmpeg-kit-react-native.podspec",
"ios",
"src",
"!android/build",
"!ios/build",
"!**/__tests__",
"!**/__fixtures__",
"!**/__mocks__"
],
"scripts": {
"test": "jest",
"lint": "eslint \"**/*.{js,ts,tsx}\"",

View File

@ -16,8 +16,6 @@ declare module 'ffmpeg-kit-react-native' {
static createMediaInformationSessionFromMap(sessionMap: { [key: string]: any }): MediaInformationSession;
getExecuteCallback(): ExecuteCallback;
getLogCallback(): LogCallback;
getSessionId(): number;
@ -58,6 +56,8 @@ declare module 'ffmpeg-kit-react-native' {
isFFprobe(): boolean;
isMediaInformation(): boolean;
cancel(): Promise<void>;
}
@ -68,13 +68,19 @@ declare module 'ffmpeg-kit-react-native' {
}
export type ExecuteCallback = (session: Session) => void;
export type FFmpegSessionCompleteCallback = (session: FFmpegSession) => void;
export type FFprobeSessionCompleteCallback = (session: FFprobeSession) => void;
export type MediaInformationSessionCompleteCallback = (session: MediaInformationSession) => void;
export class FFmpegKit {
static executeAsync(command: string, executeCallback?: ExecuteCallback, logCallback?: LogCallback, statisticsCallback?: StatisticsCallback): Promise<FFmpegSession>;
static execute(command: string): Promise<FFmpegSession>;
static executeWithArgumentsAsync(commandArguments: string[], executeCallback?: ExecuteCallback, logCallback?: LogCallback, statisticsCallback?: StatisticsCallback): Promise<FFmpegSession>;
static executeWithArguments(commandArguments: string[]): Promise<FFmpegSession>;
static executeAsync(command: string, completeCallback?: FFmpegSessionCompleteCallback, logCallback?: LogCallback, statisticsCallback?: StatisticsCallback): Promise<FFmpegSession>;
static executeWithArgumentsAsync(commandArguments: string[], completeCallback?: FFmpegSessionCompleteCallback, logCallback?: LogCallback, statisticsCallback?: StatisticsCallback): Promise<FFmpegSession>;
static cancel(sessionId?: number): Promise<void>;
@ -112,6 +118,12 @@ declare module 'ffmpeg-kit-react-native' {
static ignoreSignal(signal: Signal): Promise<void>;
static ffmpegExecute(session: FFmpegSession): Promise<void>;
static ffprobeExecute(session: FFprobeSession): Promise<void>;
static getMediaInformationExecute(session: MediaInformationSession, waitTimeout?: number): Promise<void>;
static asyncFFmpegExecute(session: FFmpegSession): Promise<void>;
static asyncFFprobeExecute(session: FFprobeSession): Promise<void>;
@ -122,12 +134,28 @@ declare module 'ffmpeg-kit-react-native' {
static enableStatisticsCallback(statisticsCallback: StatisticsCallback): void;
static enableExecuteCallback(executeCallback: ExecuteCallback): void;
static enableFFmpegSessionCompleteCallback(completeCallback: FFmpegSessionCompleteCallback): void;
static getFFmpegSessionCompleteCallback(): FFmpegSessionCompleteCallback;
static enableFFprobeSessionCompleteCallback(completeCallback: FFprobeSessionCompleteCallback): void;
static getFFprobeSessionCompleteCallback(): FFprobeSessionCompleteCallback;
static enableMediaInformationSessionCompleteCallback(completeCallback: MediaInformationSessionCompleteCallback): void;
static getMediaInformationSessionCompleteCallback(): MediaInformationSessionCompleteCallback;
static getLogLevel(): Level;
static setLogLevel(level: Level): Promise<void>;
static getSafParameterForRead(uriString: String): Promise<string>;
static getSafParameterForWrite(uriString: String): Promise<string>;
static getSafParameter(uriString: String, openMode: String): Promise<string>;
static getSessionHistorySize(): Promise<number>;
static setSessionHistorySize(sessionHistorySize: number): Promise<void>;
@ -142,6 +170,12 @@ declare module 'ffmpeg-kit-react-native' {
static clearSessions(): Promise<void>;
static getFFmpegSessions(): Promise<FFmpegSession[]>;
static getFFprobeSessions(): Promise<FFprobeSession[]>;
static getMediaInformationSessions(): Promise<MediaInformationSession[]>;
static getSessionsByState(state): Promise<Session[]>;
static getLogRedirectionStrategy(): LogRedirectionStrategy;
@ -172,22 +206,20 @@ declare module 'ffmpeg-kit-react-native' {
static selectDocumentForWrite(title?: string, type?: string, extraTypes?: string[]): Promise<string>;
static getSafParameterForRead(uriString): Promise<string>;
static getSafParameterForWrite(uriString): Promise<string>;
}
export class FFmpegSession extends AbstractSession implements Session {
constructor();
static create(argumentsArray: Array<string>, executeCallback?: ExecuteCallback, logCallback?: LogCallback, statisticsCallback?: StatisticsCallback, logRedirectionStrategy?: LogRedirectionStrategy): Promise<FFmpegSession>;
static create(argumentsArray: Array<string>, completeCallback?: FFmpegSessionCompleteCallback, logCallback?: LogCallback, statisticsCallback?: StatisticsCallback, logRedirectionStrategy?: LogRedirectionStrategy): Promise<FFmpegSession>;
static fromMap(sessionMap: { [key: string]: any }): FFmpegSession;
getStatisticsCallback(): StatisticsCallback;
getCompleteCallback(): FFmpegSessionCompleteCallback;
getAllStatistics(waitTimeout?: number): Promise<Array<Statistics>>;
getStatistics(): Promise<Array<Statistics>>;
@ -198,21 +230,35 @@ declare module 'ffmpeg-kit-react-native' {
isFFprobe(): boolean;
isMediaInformation(): boolean;
}
export class FFprobeKit {
static executeAsync(command: string, executeCallback?: ExecuteCallback, logCallback?: LogCallback): Promise<FFprobeSession>;
static execute(command: string): Promise<FFprobeSession>;
static executeWithArgumentsAsync(commandArguments: string[], executeCallback?: ExecuteCallback, logCallback?: LogCallback): Promise<FFprobeSession>;
static executeWithArguments(commandArguments: string[]): Promise<FFprobeSession>;
static getMediaInformationAsync(path: string, executeCallback?: ExecuteCallback, logCallback?: LogCallback, waitTimeout?: number): Promise<MediaInformationSession>;
static executeAsync(command: string, completeCallback?: FFprobeSessionCompleteCallback, logCallback?: LogCallback): Promise<FFprobeSession>;
static getMediaInformationFromCommandAsync(command: string, executeCallback?: ExecuteCallback, logCallback?: LogCallback, waitTimeout?: number): Promise<MediaInformationSession>;
static executeWithArgumentsAsync(commandArguments: string[], completeCallback?: FFprobeSessionCompleteCallback, logCallback?: LogCallback): Promise<FFprobeSession>;
static getMediaInformationFromCommandArgumentsAsync(commandArguments: string[], executeCallback?: ExecuteCallback, logCallback?: LogCallback, waitTimeout?: number): Promise<MediaInformationSession>;
static getMediaInformation(path: string, waitTimeout?: number): Promise<MediaInformationSession>;
static listSessions(): Promise<FFprobeSession[]>;
static getMediaInformationFromCommand(command: string, waitTimeout?: number): Promise<MediaInformationSession>;
static getMediaInformationFromCommandArguments(commandArguments: string[], waitTimeout?: number): Promise<MediaInformationSession>;
static getMediaInformationAsync(path: string, completeCallback?: FFprobeSessionCompleteCallback, logCallback?: LogCallback, waitTimeout?: number): Promise<MediaInformationSession>;
static getMediaInformationFromCommandAsync(command: string, completeCallback?: FFprobeSessionCompleteCallback, logCallback?: LogCallback, waitTimeout?: number): Promise<MediaInformationSession>;
static getMediaInformationFromCommandArgumentsAsync(commandArguments: string[], completeCallback?: FFprobeSessionCompleteCallback, logCallback?: LogCallback, waitTimeout?: number): Promise<MediaInformationSession>;
static listFFprobeSessions(): Promise<FFprobeSession[]>;
static listMediaInformationSessions(): Promise<MediaInformationSession[]>;
}
@ -220,14 +266,18 @@ declare module 'ffmpeg-kit-react-native' {
constructor();
static create(argumentsArray: Array<string>, executeCallback?: ExecuteCallback, logCallback?: LogCallback, logRedirectionStrategy?: LogRedirectionStrategy): Promise<FFprobeSession>;
static create(argumentsArray: Array<string>, completeCallback?: FFprobeSessionCompleteCallback, logCallback?: LogCallback, logRedirectionStrategy?: LogRedirectionStrategy): Promise<FFprobeSession>;
static fromMap(sessionMap: { [key: string]: any }): FFprobeSession;
getCompleteCallback(): FFprobeSessionCompleteCallback;
isFFmpeg(): boolean;
isFFprobe(): boolean;
isMediaInformation(): boolean;
}
export class Level {
@ -299,6 +349,8 @@ declare module 'ffmpeg-kit-react-native' {
getStreams(): Array<StreamInformation>;
getChapters(): Array<Chapter>;
getStringProperty(key: string): string;
getNumberProperty(key: string): number;
@ -319,11 +371,11 @@ declare module 'ffmpeg-kit-react-native' {
}
export class MediaInformationSession extends FFprobeSession {
export class MediaInformationSession extends AbstractSession implements Session {
constructor();
static create(argumentsArray: Array<string>, executeCallback?: ExecuteCallback, logCallback?: LogCallback): Promise<MediaInformationSession>;
static create(argumentsArray: Array<string>, completeCallback?: MediaInformationSessionCompleteCallback, logCallback?: LogCallback): Promise<MediaInformationSession>;
static fromMap(sessionMap: { [key: string]: any }): MediaInformationSession;
@ -331,6 +383,14 @@ declare module 'ffmpeg-kit-react-native' {
setMediaInformation(mediaInformation: MediaInformation): void;
getCompleteCallback(): MediaInformationSessionCompleteCallback;
isFFmpeg(): boolean;
isFFprobe(): boolean;
isMediaInformation(): boolean;
}
export class Packages {
@ -365,8 +425,6 @@ declare module 'ffmpeg-kit-react-native' {
export interface Session {
getExecuteCallback(): ExecuteCallback;
getLogCallback(): LogCallback;
getSessionId(): number;
@ -407,6 +465,8 @@ declare module 'ffmpeg-kit-react-native' {
isFFprobe(): boolean;
isMediaInformation(): boolean;
cancel(): Promise<void>;
}
@ -535,4 +595,40 @@ declare module 'ffmpeg-kit-react-native' {
}
export class Chapter {
static readonly KEY_ID: string;
static readonly KEY_TIME_BASE: string;
static readonly KEY_START: string;
static readonly KEY_START_TIME: string;
static readonly KEY_END: string;
static readonly KEY_END_TIME: string;
static readonly KEY_TAGS: string;
constructor(properties: Record<string, any>);
getId(): number;
getTimeBase(): string;
getStart(): number;
getStartTime(): string;
getEnd(): number;
getEndTime(): string;
getTags(): Record<string, any>;
getStringProperty(key): string;
getNumberProperty(key): number;
getProperties(key): Record<string, any>;
getAllProperties(): Record<string, any>;
}
}

File diff suppressed because it is too large Load Diff