Page MenuHomePhabricator

D13021.id43275.diff
No OneTemporary

D13021.id43275.diff

diff --git a/lib/media/video-utils.js b/lib/media/video-utils.js
--- a/lib/media/video-utils.js
+++ b/lib/media/video-utils.js
@@ -97,14 +97,16 @@
);
const outputPath = `${outputDirectory}${outputFilename}`;
- let quality, speed, scale;
- if (outputCodec === 'h264') {
+ let hardwareAcceleration, quality, speed, scale;
+ if (outputCodec === 'h264_mediacodec') {
+ hardwareAcceleration = 'mediacodec';
const { floor, min, max, log2 } = Math;
const crf = floor(min(5, max(0, log2(inputDuration / 5)))) + 23;
quality = `-crf ${crf}`;
speed = '-preset ultrafast';
scale = `-vf scale=${maxWidth}:${maxHeight}:force_original_aspect_ratio=decrease`;
} else if (outputCodec === 'h264_videotoolbox') {
+ hardwareAcceleration = 'videotoolbox';
quality = '-profile:v baseline';
speed = '-realtime 1';
const { width, height } = inputDimensions;
@@ -120,10 +122,11 @@
}
const ffmpegCommand =
+ `-hwaccel ${hardwareAcceleration} ` +
`-i ${inputPath} ` +
`-c:a copy -c:v ${outputCodec} ` +
`${quality} ` +
- '-vsync 2 -r 30 ' +
+ '-fps_mode cfr -r 30 ' +
`${scale} ` +
`${speed} ` +
'-movflags +faststart ' +
diff --git a/native/android/build.gradle b/native/android/build.gradle
--- a/native/android/build.gradle
+++ b/native/android/build.gradle
@@ -31,7 +31,7 @@
}
ext {
- reactNativeFFmpegPackage = "min-gpl-lts"
+ ffmpegKitPackage = "min-gpl-lts"
}
allprojects {
diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj
--- a/native/ios/Comm.xcodeproj/project.pbxproj
+++ b/native/ios/Comm.xcodeproj/project.pbxproj
@@ -1171,11 +1171,27 @@
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Comm/Pods-Comm-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/ffmpegkit.framework/ffmpegkit",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavcodec.framework/libavcodec",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavdevice.framework/libavdevice",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavfilter.framework/libavfilter",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavformat.framework/libavformat",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libavutil.framework/libavutil",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libswresample.framework/libswresample",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-min/libswscale.framework/libswscale",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ffmpegkit.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavcodec.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavdevice.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavfilter.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavformat.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavutil.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libswresample.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libswscale.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1413,7 +1429,6 @@
"\"${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/lottie-react-native\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-camera\"",
- "\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-ffmpeg\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-in-app-message\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-netinfo\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications\"",
@@ -1555,7 +1570,6 @@
"\"${PODS_CONFIGURATION_BUILD_DIR}/lottie-ios\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/lottie-react-native\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-camera\"",
- "\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-ffmpeg\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-in-app-message\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-netinfo\"",
"\"${PODS_CONFIGURATION_BUILD_DIR}/react-native-notifications\"",
diff --git a/native/ios/Podfile b/native/ios/Podfile
--- a/native/ios/Podfile
+++ b/native/ios/Podfile
@@ -10,7 +10,7 @@
def common_comm_target_pods
pod 'SQLCipher-Amalgamation', :path => '../../node_modules/@commapp/sqlcipher-amalgamation'
pod 'react-native-video/VideoCaching', :podspec => '../node_modules/react-native-video'
- pod 'react-native-ffmpeg/min-lts', :podspec => '../node_modules/react-native-ffmpeg'
+ pod 'ffmpeg-kit-react-native', :subspecs => ['min'], :podspec => '../node_modules/ffmpeg-kit-react-native'
end
post_integrate do |installer|
diff --git a/native/ios/Podfile.lock b/native/ios/Podfile.lock
--- a/native/ios/Podfile.lock
+++ b/native/ios/Podfile.lock
@@ -132,6 +132,10 @@
- React-Core (= 0.70.9)
- React-jsi (= 0.70.9)
- ReactCommon/turbomodule/core (= 0.70.9)
+ - ffmpeg-kit-ios-min (6.0)
+ - ffmpeg-kit-react-native/min (6.0.2):
+ - ffmpeg-kit-ios-min (= 6.0)
+ - React-Core
- fmt (6.2.1)
- glog (0.3.5)
- hermes-engine (0.70.9)
@@ -163,7 +167,6 @@
- MMKVAppExtension (1.3.5):
- MMKVCore (~> 1.3.5)
- MMKVCore (1.3.5)
- - mobile-ffmpeg-min (4.3.1.LTS)
- OLMKit (3.2.14):
- OLMKit/olmc (= 3.2.14)
- OLMKit/olmcpp (= 3.2.14)
@@ -404,9 +407,6 @@
- React
- react-native-camera/RN (3.31.0):
- React
- - react-native-ffmpeg/min-lts (0.4.4):
- - mobile-ffmpeg-min (= 4.3.1.LTS)
- - React
- react-native-in-app-message (1.0.2):
- React
- react-native-netinfo (9.3.7):
@@ -605,6 +605,7 @@
- EXUpdatesInterface (from `../../node_modules/expo-updates-interface/ios`)
- FBLazyVector (from `../../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../../node_modules/react-native/React/FBReactNativeSpec`)
+ - ffmpeg-kit-react-native/min (from `../node_modules/ffmpeg-kit-react-native`)
- glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (from `../../node_modules/react-native/sdks/hermes/hermes-engine.podspec`)
- libevent (~> 2.1.12)
@@ -629,7 +630,6 @@
- React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../../node_modules/react-native/ReactCommon/logger`)
- react-native-camera (from `../node_modules/react-native-camera`)
- - react-native-ffmpeg/min-lts (from `../node_modules/react-native-ffmpeg`)
- react-native-in-app-message (from `../node_modules/react-native-in-app-message`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
@@ -668,6 +668,7 @@
SPEC REPOS:
trunk:
- DVAssetLoaderDelegate
+ - ffmpeg-kit-ios-min
- fmt
- libaom
- libavif
@@ -678,7 +679,6 @@
- MMKV
- MMKVAppExtension
- MMKVCore
- - mobile-ffmpeg-min
- OpenSSL-Universal
- SDWebImage
- SDWebImageAVIFCoder
@@ -744,6 +744,8 @@
:path: "../../node_modules/react-native/Libraries/FBLazyVector"
FBReactNativeSpec:
:path: "../../node_modules/react-native/React/FBReactNativeSpec"
+ ffmpeg-kit-react-native:
+ :podspec: "../node_modules/ffmpeg-kit-react-native"
glog:
:podspec: "../../node_modules/react-native/third-party-podspecs/glog.podspec"
hermes-engine:
@@ -784,8 +786,6 @@
:path: "../../node_modules/react-native/ReactCommon/logger"
react-native-camera:
:path: "../node_modules/react-native-camera"
- react-native-ffmpeg:
- :podspec: "../node_modules/react-native-ffmpeg"
react-native-in-app-message:
:path: "../node_modules/react-native-in-app-message"
react-native-netinfo:
@@ -885,6 +885,8 @@
EXUpdatesInterface: bffd1ead18f0bab04fa784ca159c115607b8a23c
FBLazyVector: bc76253beb7463b688aa6af913b822ed631de31a
FBReactNativeSpec: 2dfdfdc025c136effd657e62879c66122718030b
+ ffmpeg-kit-ios-min: 4e9a088f4ee9629435960b9d68e54848975f1931
+ ffmpeg-kit-react-native: 3cea88c9c5cfad62e1465279ea7d800dfbba3b00
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: 918ec5addfbc430c9f443376d739f088b6dc96c3
@@ -898,7 +900,6 @@
MMKV: 506311d0494023c2f7e0b62cc1f31b7370fa3cfb
MMKVAppExtension: 0cb4ebe918cb739fea57f9ed892c050d7c4d2cf6
MMKVCore: 9e2e5fd529b64a9fe15f1a7afb3d73b2e27b4db9
- mobile-ffmpeg-min: d5d22dcef5c8ec56f771258f1f5be245d914f193
OLMKit: a13e1a20579e88d03971c5821360be24949a1a09
OpenSSL-Universal: 84efb8a29841f2764ac5403e0c4119a28b713346
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
@@ -917,7 +918,6 @@
React-jsinspector: d76d32327f21d4f40dcf696231fdbbca60de4711
React-logger: 1b3522f1e05c6360e93df3607a016c39e30a7351
react-native-camera: b5c8c7a71feecfdd5b39f0dbbf6b64b957ed55f2
- react-native-ffmpeg: f9a60452aaa5d478aac205b248224994f3bde416
react-native-in-app-message: f91de5009620af01456531118264c93e249b83ec
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
@@ -959,6 +959,6 @@
Yoga: dc109b79db907f0f589fc423e991b09ec42d2295
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
-PODFILE CHECKSUM: 3ad7489a9ca814690867cca40f302b9432cebe02
+PODFILE CHECKSUM: 08ac12954526f5d7b062d36d800e1b628afe9040
COCOAPODS: 1.14.3
diff --git a/native/media/ffmpeg.js b/native/media/ffmpeg.js
--- a/native/media/ffmpeg.js
+++ b/native/media/ffmpeg.js
@@ -1,6 +1,10 @@
// @flow
-import { RNFFmpeg, RNFFprobe, RNFFmpegConfig } from 'react-native-ffmpeg';
+import {
+ FFmpegKit,
+ FFprobeKit,
+ FFmpegKitConfig,
+} from 'ffmpeg-kit-react-native';
import { getHasMultipleFramesProbeCommand } from 'lib/media/video-utils.js';
import type {
@@ -85,19 +89,26 @@
): Promise<{ rc: number, lastStats: ?FFmpegStatistics }> {
const duration = inputVideoDuration > 0 ? inputVideoDuration : 0.001;
const wrappedCommand = async () => {
- RNFFmpegConfig.resetStatistics();
let lastStats;
if (onTranscodingProgress) {
- RNFFmpegConfig.enableStatisticsCallback(
- (statisticsData: FFmpegStatistics) => {
- lastStats = statisticsData;
- const { time } = statisticsData;
- onTranscodingProgress(time / 1000 / duration);
- },
- );
+ FFmpegKitConfig.enableStatisticsCallback(statisticsObject => {
+ const time = statisticsObject.getTime();
+ onTranscodingProgress(time / 1000 / duration);
+ lastStats = {
+ speed: statisticsObject.getSpeed(),
+ time,
+ size: statisticsObject.getSize(),
+ videoQuality: statisticsObject.getVideoQuality(),
+ videoFrameNumber: statisticsObject.getVideoFrameNumber(),
+ videoFps: statisticsObject.getVideoFps(),
+ bitrate: statisticsObject.getBitrate(),
+ };
+ });
}
- const ffmpegResult = await RNFFmpeg.execute(ffmpegCommand);
- return { ...ffmpegResult, lastStats };
+ const session = await FFmpegKit.execute(ffmpegCommand);
+ const returnCode = await session.getReturnCode();
+ const rc = returnCode.getValue();
+ return { rc, lastStats };
};
return this.queueCommand('process', wrappedCommand);
}
@@ -112,9 +123,10 @@
videoPath: string,
outputPath: string,
): Promise<number> {
- const thumbnailCommand = `-i ${videoPath} -frames 1 -f singlejpeg ${outputPath}`;
- const { rc } = await RNFFmpeg.execute(thumbnailCommand);
- return rc;
+ const thumbnailCommand = `-i ${videoPath} -frames 1 -f mjpeg ${outputPath}`;
+ const session = await FFmpegKit.execute(thumbnailCommand);
+ const returnCode = await session.getReturnCode();
+ return returnCode.getValue();
}
getVideoInfo(path: string): Promise<VideoInfo> {
@@ -123,26 +135,28 @@
}
static async innerGetVideoInfo(path: string): Promise<VideoInfo> {
- const info = await RNFFprobe.getMediaInformation(path);
+ const session = await FFprobeKit.getMediaInformation(path);
+ const info = await session.getMediaInformation();
const videoStreamInfo = FFmpeg.getVideoStreamInfo(info);
const codec = videoStreamInfo?.codec;
const dimensions = videoStreamInfo && videoStreamInfo.dimensions;
- const format = info.format.split(',');
- const duration = info.duration / 1000;
+ const format = info.getFormat().split(',');
+ const duration = info.getDuration();
return { codec, format, dimensions, duration };
}
static getVideoStreamInfo(
info: Object,
): ?{ +codec: string, +dimensions: Dimensions } {
- if (!info.streams) {
+ const streams = info.getStreams();
+ if (!streams) {
return null;
}
- for (const stream of info.streams) {
- if (stream.type === 'video') {
- const codec: string = stream.codec;
- const width: number = stream.width;
- const height: number = stream.height;
+ for (const stream of streams) {
+ if (stream.getType() === 'video') {
+ const codec: string = stream.getCodec();
+ const width: number = stream.getWidth();
+ const height: number = stream.getHeight();
return { codec, dimensions: { width, height } };
}
}
@@ -155,9 +169,11 @@
}
static async innerHasMultipleFrames(path: string): Promise<boolean> {
- await RNFFprobe.execute(getHasMultipleFramesProbeCommand(path));
- const probeOutput = await RNFFmpegConfig.getLastCommandOutput();
- const numFrames = parseInt(probeOutput.lastCommandOutput);
+ const session = await FFprobeKit.execute(
+ getHasMultipleFramesProbeCommand(path),
+ );
+ const probeOutput = await session.getOutput();
+ const numFrames = parseInt(probeOutput);
return numFrames > 1;
}
}
diff --git a/native/media/video-utils.js b/native/media/video-utils.js
--- a/native/media/video-utils.js
+++ b/native/media/video-utils.js
@@ -79,12 +79,9 @@
inputDuration: duration,
inputDimensions: input.dimensions,
outputDirectory: temporaryDirectoryPath,
- // We want ffmpeg to use hardware-accelerated encoders. On iOS we can do
- // this using VideoToolbox, but ffmpeg on Android is still missing
- // MediaCodec encoding support: https://trac.ffmpeg.org/ticket/6407
outputCodec: Platform.select({
ios: 'h264_videotoolbox',
- //android: 'h264_mediacodec',
+ android: 'h264_mediacodec',
default: 'h264',
}),
clientConnectionInfo: {
diff --git a/native/package.json b/native/package.json
--- a/native/package.json
+++ b/native/package.json
@@ -84,6 +84,7 @@
"expo-media-library": "~15.0.0",
"expo-secure-store": "~12.0.0",
"expo-splash-screen": "~0.17.4",
+ "ffmpeg-kit-react-native": "^6.0.2",
"find-root": "^1.1.0",
"invariant": "^2.2.4",
"lib": "0.0.1",
@@ -95,7 +96,6 @@
"react-native": "0.70.9",
"react-native-camera": "^3.31.0",
"react-native-device-info": "^10.3.0",
- "react-native-ffmpeg": "^0.4.4",
"react-native-figma-squircle": "^0.1.2",
"react-native-floating-action": "^1.22.0",
"react-native-fs": "^2.20.0",
diff --git a/patches/react-native-ffmpeg+0.4.4.patch b/patches/react-native-ffmpeg+0.4.4.patch
deleted file mode 100644
--- a/patches/react-native-ffmpeg+0.4.4.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/node_modules/react-native-ffmpeg/android/build.gradle b/node_modules/react-native-ffmpeg/android/build.gradle
-index 32923e4..283b63c 100644
---- a/node_modules/react-native-ffmpeg/android/build.gradle
-+++ b/node_modules/react-native-ffmpeg/android/build.gradle
-@@ -14,6 +14,7 @@ apply plugin: 'com.android.library'
-
- buildscript {
- repositories {
-+ gradlePluginPortal()
- jcenter()
- maven { url 'https://maven.google.com' }
- }
diff --git a/yarn.lock b/yarn.lock
--- a/yarn.lock
+++ b/yarn.lock
@@ -11836,6 +11836,11 @@
biskviit "1.0.1"
encoding "0.1.12"
+ffmpeg-kit-react-native@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/ffmpeg-kit-react-native/-/ffmpeg-kit-react-native-6.0.2.tgz#9eeac96ad89367c99480bd90431391405d4eb73e"
+ integrity sha512-r9uSmahq8TeyIb7fXf3ft+uUXyoeWRFa99+khjo0TAzWO9y0z9wU7eGnab9JLw1MmCB9v64o4yojNluJhVm9nQ==
+
figma-squircle@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/figma-squircle/-/figma-squircle-0.1.2.tgz#fa97de644131d99f2c42a2d8b70d56a36783c234"
@@ -20253,11 +20258,6 @@
resolved "https://registry.yarnpkg.com/react-native-device-info/-/react-native-device-info-10.3.0.tgz#6bab64d84d3415dd00cc446c73ec5e2e61fddbe7"
integrity sha512-/ziZN1sA1REbJTv5mQZ4tXggcTvSbct+u5kCaze8BmN//lbxcTvWsU6NQd4IihLt89VkbX+14IGc9sVApSxd/w==
-react-native-ffmpeg@^0.4.4:
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/react-native-ffmpeg/-/react-native-ffmpeg-0.4.4.tgz#9f4dbda53c96078cecbbe83a866d4b535b957131"
- integrity sha512-MUBV3Xvto1Hl049Y9EaOZdjazkK1ixQzCzPEt1o7V2duSOrM2kJ2o/RiC4rSRgapU2uqYRHMZ6X4JJI7y40qXw==
-
react-native-figma-squircle@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/react-native-figma-squircle/-/react-native-figma-squircle-0.1.2.tgz#64973afcfb42a53cc662ac2ccfba73ced7297124"

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 2:52 PM (19 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2571263
Default Alt Text
D13021.id43275.diff (17 KB)

Event Timeline