diff --git a/lib/types/media-types.js b/lib/types/media-types.js --- a/lib/types/media-types.js +++ b/lib/types/media-types.js @@ -129,10 +129,10 @@ }; export type VideoInfo = { - +codec: ?string, - +dimensions: ?Dimensions, + +codec: string, + +dimensions: Dimensions, +duration: number, // seconds - +format: $ReadOnlyArray<string>, + +format: string, }; export type VideoProbeMediaMissionStep = { @@ -144,7 +144,7 @@ +validFormat: boolean, +duration: ?number, // seconds +codec: ?string, - +format: ?$ReadOnlyArray<string>, + +format: ?string, +dimensions: ?Dimensions, }; diff --git a/native/media/ffmpeg.js b/native/media/ffmpeg.js --- a/native/media/ffmpeg.js +++ b/native/media/ffmpeg.js @@ -7,11 +7,9 @@ } from 'ffmpeg-kit-react-native'; import { getHasMultipleFramesProbeCommand } from 'lib/media/video-utils.js'; -import type { - Dimensions, - FFmpegStatistics, - VideoInfo, -} from 'lib/types/media-types.js'; +import type { FFmpegStatistics, VideoInfo } from 'lib/types/media-types.js'; + +import { getVideoInfo } from '../utils/media-module.js'; const maxSimultaneousCalls = { process: 1, @@ -135,32 +133,14 @@ } static async innerGetVideoInfo(path: string): Promise<VideoInfo> { - 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.getFormat().split(','); - const duration = info.getDuration(); - return { codec, format, dimensions, duration }; - } + const info = await getVideoInfo(path); - static getVideoStreamInfo( - info: Object, - ): ?{ +codec: string, +dimensions: Dimensions } { - const streams = info.getStreams(); - if (!streams) { - return null; - } - 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 } }; - } - } - return null; + return { + codec: info.codec, + format: info.format, + dimensions: { width: info.width, height: info.height }, + duration: info.duration, + }; } hasMultipleFrames(path: string): Promise<boolean> { 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 @@ -29,6 +29,9 @@ }); const clientTranscodeSpeed = 1.15; // in seconds of video transcoded per second +const validCodecs = ['avc', 'avc1', 'h264']; +const validFormats = ['mp4']; + type ProcessVideoInfo = { +uri: string, +mime: string, @@ -258,7 +261,7 @@ try { ({ codec, format, dimensions, duration } = await ffmpeg.getVideoInfo(path)); success = true; - validFormat = codec === 'h264' && format.includes('mp4'); + validFormat = validCodecs.includes(codec) && validFormats.includes(format); } catch (e) { exceptionMessage = getMessageForException(e); } diff --git a/native/utils/media-module.js b/native/utils/media-module.js --- a/native/utils/media-module.js +++ b/native/utils/media-module.js @@ -2,5 +2,18 @@ import { requireNativeModule } from 'expo-modules-core'; -// eslint-disable-next-line no-unused-vars -const MediaModule: {} = requireNativeModule('MediaModule'); +type VideoInfo = { + +duration: number, // seconds + +width: number, + +height: number, + +codec: string, + +format: string, +}; + +const MediaModule: { + +getVideoInfo: (path: string) => Promise<VideoInfo>, +} = requireNativeModule('MediaModule'); + +export function getVideoInfo(path: string): Promise<VideoInfo> { + return MediaModule.getVideoInfo(path); +}