import {NativeEventEmitter, NativeModules} from 'react-native'; const {FFmpegKitReactNativeModule} = NativeModules; const ffmpegSessionCompleteCallbackMap = new Map() const ffprobeSessionCompleteCallbackMap = new Map() const mediaInformationSessionCompleteCallbackMap = new Map() const logCallbackMap = new Map() const statisticsCallbackMap = new Map() const logRedirectionStrategyMap = new Map() const eventLogCallbackEvent = "FFmpegKitLogCallbackEvent"; const eventStatisticsCallbackEvent = "FFmpegKitStatisticsCallbackEvent"; const eventCompleteCallbackEvent = "FFmpegKitCompleteCallbackEvent"; export const LogRedirectionStrategy = { ALWAYS_PRINT_LOGS: 0, PRINT_LOGS_WHEN_NO_CALLBACKS_DEFINED: 1, PRINT_LOGS_WHEN_GLOBAL_CALLBACK_NOT_DEFINED: 2, PRINT_LOGS_WHEN_SESSION_CALLBACK_NOT_DEFINED: 3, NEVER_PRINT_LOGS: 4 } export const SessionState = { CREATED: 0, RUNNING: 1, FAILED: 2, COMPLETED: 3 } export const Signal = { SIGINT: 2, SIGQUIT: 3, SIGPIPE: 13, SIGTERM: 15, SIGXCPU: 24 } class FFmpegKitReactNativeEventEmitter extends NativeEventEmitter { constructor() { super(FFmpegKitReactNativeModule); } addListener(eventType, listener, context) { let subscription = super.addListener(eventType, listener, context); subscription.eventType = eventType; let subscriptionRemove = subscription.remove; subscription.remove = () => { if (super.removeSubscription != null) { super.removeSubscription(subscription); } else if (subscriptionRemove != null) { subscriptionRemove(); } }; return subscription; } removeSubscription(subscription) { if (super.removeSubscription) { super.removeSubscription(subscription); } } } /** *

Common interface for all FFmpegKit sessions. */ export class Session { /** * Returns the session specific log callback. * * @return session specific log callback */ getLogCallback() { } /** * Returns the session identifier. * * @return session identifier */ getSessionId() { } /** * Returns session create time. * * @return session create time */ getCreateTime() { } /** * Returns session start time. * * @return session start time */ getStartTime() { } /** * Returns session end time. * * @return session end time */ getEndTime() { } /** * Returns the time taken to execute this session. * * @return time taken to execute this session in milliseconds or zero (0) if the session is * not over yet */ getDuration() { } /** * Returns command arguments as an array. * * @return command arguments as an array */ getArguments() { } /** * Returns command arguments as a concatenated string. * * @return command arguments as a concatenated string */ getCommand() { } /** * Returns all log entries generated for this session. If there are asynchronous * messages that are not delivered yet, this method waits for them until the given timeout. * * @param waitTimeout wait timeout for asynchronous messages in milliseconds * @return list of log entries generated for this session */ getAllLogs(waitTimeout) { } /** * Returns all log entries delivered for this session. Note that if there are asynchronous log * messages that are not delivered yet, this method will not wait for them and will return * immediately. * * @return list of log entries received for this session */ getLogs() { } /** * Returns all log entries generated for this session as a concatenated string. If there are * asynchronous messages that are not delivered yet, this method waits for them until * the given timeout. * * @param waitTimeout wait timeout for asynchronous messages in milliseconds * @return all log entries generated for this session as a concatenated string */ getAllLogsAsString(waitTimeout) { } /** * Returns all log entries delivered for this session as a concatenated string. Note that if * there are asynchronous log messages that are not delivered yet, this method will not wait * for them and will return immediately. * * @return list of log entries received for this session */ getLogsAsString() { } /** * Returns the log output generated while running the session. * * @return log output generated */ getOutput() { } /** * Returns the state of the session. * * @return state of the session */ getState() { } /** * Returns the return code for this session. Note that return code is only set for sessions * that end with COMPLETED state. If a session is not started, still running or failed then * this method returns undefined. * * @return the return code for this session if the session is COMPLETED, undefined if session is * not started, still running or failed */ getReturnCode() { } /** * Returns the stack trace of the exception received while executing this session. *

* The stack trace is only set for sessions that end with FAILED state. For sessions that has * COMPLETED state this method returns undefined. * * @return stack trace of the exception received while executing this session, undefined if session * is not started, still running or completed */ getFailStackTrace() { } /** * Returns session specific log redirection strategy. * * @return session specific log redirection strategy */ getLogRedirectionStrategy() { } /** * Returns whether there are still asynchronous messages being transmitted for this * session or not. * * @return true if there are still asynchronous messages being transmitted, false * otherwise */ thereAreAsynchronousMessagesInTransmit() { } /** * Returns whether it is an FFmpeg session or not. * * @return true if it is an FFmpeg session, false otherwise */ isFFmpeg() { } /** * Returns whether it is an FFprobe session or not. * * @return true if it is an FFprobe session, false otherwise */ isFFprobe() { } /** * Returns whether it is a MediaInformation session or not. * * @return true if it is a MediaInformation session, false otherwise */ isMediaInformation() { } /** * Cancels running the session. */ cancel() { } } /** * Abstract session implementation which includes common features shared by FFmpeg, * FFprobe and MediaInformation sessions. */ export class AbstractSession extends Session { /** * Defines how long default "getAll" methods wait, in milliseconds. */ static DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT = 5000; /** * Session identifier. */ #sessionId; /** * Date and time the session was created. */ #createTime; /** * Date and time the session was started. */ #startTime; /** * Command string. */ #command; /** * Command arguments as an array. */ #argumentsArray; /** * Session specific log redirection strategy. */ #logRedirectionStrategy; /** * Creates a new abstract session. */ constructor() { super(); } /** * Creates a new FFmpeg session. * * @param argumentsArray FFmpeg command arguments * @param logRedirectionStrategy defines how logs will be redirected * @returns FFmpeg session created */ static async createFFmpegSession(argumentsArray, logRedirectionStrategy) { await FFmpegKitConfig.init(); if (logRedirectionStrategy === undefined) { logRedirectionStrategy = FFmpegKitConfig.getLogRedirectionStrategy(); } let nativeSession = await FFmpegKitReactNativeModule.ffmpegSession(argumentsArray); let session = new FFmpegSession(); session.#sessionId = nativeSession.sessionId; session.#createTime = FFmpegKitFactory.validDate(nativeSession.createTime); session.#startTime = FFmpegKitFactory.validDate(nativeSession.startTime); session.#command = nativeSession.command; session.#argumentsArray = argumentsArray; session.#logRedirectionStrategy = logRedirectionStrategy; FFmpegKitFactory.setLogRedirectionStrategy(session.#sessionId, logRedirectionStrategy); return session; } /** * Creates a new FFmpeg session from the given map. * * @param sessionMap map that includes session fields as map keys * @returns FFmpeg session created */ static createFFmpegSessionFromMap(sessionMap) { let session = new FFmpegSession(); session.#sessionId = sessionMap.sessionId; session.#createTime = FFmpegKitFactory.validDate(sessionMap.createTime); session.#startTime = FFmpegKitFactory.validDate(sessionMap.startTime); session.#command = sessionMap.command; session.#argumentsArray = FFmpegKitConfig.parseArguments(sessionMap.command); session.#logRedirectionStrategy = FFmpegKitFactory.getLogRedirectionStrategy(session.#sessionId); return session; } /** * Creates a new FFprobe session. * * @param argumentsArray FFprobe command arguments * @param logRedirectionStrategy defines how logs will be redirected * @returns FFprobe session created */ static async createFFprobeSession(argumentsArray, logRedirectionStrategy) { await FFmpegKitConfig.init(); if (logRedirectionStrategy === undefined) { logRedirectionStrategy = FFmpegKitConfig.getLogRedirectionStrategy(); } let nativeSession = await FFmpegKitReactNativeModule.ffprobeSession(argumentsArray); let session = new FFprobeSession(); session.#sessionId = nativeSession.sessionId; session.#createTime = FFmpegKitFactory.validDate(nativeSession.createTime); session.#startTime = FFmpegKitFactory.validDate(nativeSession.startTime); session.#command = nativeSession.command; session.#argumentsArray = argumentsArray; session.#logRedirectionStrategy = logRedirectionStrategy; FFmpegKitFactory.setLogRedirectionStrategy(session.#sessionId, logRedirectionStrategy); return session; } /** * Creates a new FFprobe session from the given map. * * @param sessionMap map that includes session fields as map keys * @returns FFprobe session created */ static createFFprobeSessionFromMap(sessionMap) { let session = new FFprobeSession(); session.#sessionId = sessionMap.sessionId; session.#createTime = FFmpegKitFactory.validDate(sessionMap.createTime); session.#startTime = FFmpegKitFactory.validDate(sessionMap.startTime); session.#command = sessionMap.command; session.#argumentsArray = FFmpegKitConfig.parseArguments(sessionMap.command); session.#logRedirectionStrategy = FFmpegKitFactory.getLogRedirectionStrategy(session.#sessionId); return session; } /** * Creates a new MediaInformationSession session. * * @param argumentsArray FFprobe command arguments * @returns MediaInformationSession session created */ static async createMediaInformationSession(argumentsArray) { await FFmpegKitConfig.init(); let nativeSession = await FFmpegKitReactNativeModule.mediaInformationSession(argumentsArray); let session = new MediaInformationSession(); session.#sessionId = nativeSession.sessionId; session.#createTime = FFmpegKitFactory.validDate(nativeSession.createTime); session.#startTime = FFmpegKitFactory.validDate(nativeSession.startTime); session.#command = nativeSession.command; session.#argumentsArray = argumentsArray; session.#logRedirectionStrategy = LogRedirectionStrategy.NEVER_PRINT_LOGS; FFmpegKitFactory.setLogRedirectionStrategy(session.#sessionId, LogRedirectionStrategy.NEVER_PRINT_LOGS); return session; } /** * Creates a new MediaInformationSession from the given map. * * @param sessionMap map that includes session fields as map keys * @returns MediaInformationSession created */ static createMediaInformationSessionFromMap(sessionMap) { let session = new MediaInformationSession(); session.#sessionId = sessionMap.sessionId; session.#createTime = FFmpegKitFactory.validDate(sessionMap.createTime); session.#startTime = FFmpegKitFactory.validDate(sessionMap.startTime); session.#command = sessionMap.command; session.#argumentsArray = FFmpegKitConfig.parseArguments(sessionMap.command); session.#logRedirectionStrategy = LogRedirectionStrategy.NEVER_PRINT_LOGS; if (sessionMap.mediaInformation !== undefined && sessionMap.mediaInformation !== null) { session.setMediaInformation(new MediaInformation(sessionMap.mediaInformation)); } return session; } /** * Returns the session specific log callback. * * @return session specific log callback */ getLogCallback() { return FFmpegKitFactory.getLogCallback(this.getSessionId()) } /** * Returns the session identifier. * * @return session identifier */ getSessionId() { return this.#sessionId; } /** * Returns session create time. * * @return session create time */ getCreateTime() { return this.#createTime; } /** * Returns session start time. * * @return session start time */ getStartTime() { return this.#startTime; } /** * Returns session end time. * * @return session end time */ async getEndTime() { const endTime = FFmpegKitReactNativeModule.abstractSessionGetEndTime(this.getSessionId()); return FFmpegKitFactory.validDate(endTime); } /** * Returns the time taken to execute this session. * * @return time taken to execute this session in milliseconds or zero (0) if the session is * not over yet */ getDuration() { return FFmpegKitReactNativeModule.abstractSessionGetDuration(this.getSessionId()); } /** * Returns command arguments as an array. * * @return command arguments as an array */ getArguments() { return this.#argumentsArray; } /** * Returns command arguments as a concatenated string. * * @return command arguments as a concatenated string */ getCommand() { return this.#command; } /** * Returns all log entries generated for this session. If there are asynchronous * messages that are not delivered yet, this method waits for them until the given timeout. * * @param waitTimeout wait timeout for asynchronous messages in milliseconds * @return list of log entries generated for this session */ async getAllLogs(waitTimeout) { const allLogs = await FFmpegKitReactNativeModule.abstractSessionGetAllLogs(this.getSessionId(), FFmpegKitFactory.optionalNumericParameter(waitTimeout)); return allLogs.map(FFmpegKitFactory.mapToLog); } /** * Returns all log entries delivered for this session. Note that if there are asynchronous log * messages that are not delivered yet, this method will not wait for them and will return * immediately. * * @return list of log entries received for this session */ async getLogs() { const logs = await FFmpegKitReactNativeModule.abstractSessionGetLogs(this.getSessionId()); return logs.map(FFmpegKitFactory.mapToLog); } /** * Returns all log entries generated for this session as a concatenated string. If there are * asynchronous messages that are not delivered yet, this method waits for them until * the given timeout. * * @param waitTimeout wait timeout for asynchronous messages in milliseconds * @return all log entries generated for this session as a concatenated string */ async getAllLogsAsString(waitTimeout) { return FFmpegKitReactNativeModule.abstractSessionGetAllLogsAsString(this.getSessionId(), FFmpegKitFactory.optionalNumericParameter(waitTimeout)); } /** * Returns all log entries delivered for this session as a concatenated string. Note that if * there are asynchronous log messages that are not delivered yet, this method will not wait * for them and will return immediately. * * @return list of log entries received for this session */ async getLogsAsString() { let logs = await this.getLogs(); let concatenatedString = ''; logs.forEach(log => concatenatedString += log.getMessage()); return concatenatedString; } /** * Returns the log output generated while running the session. * * @return log output generated */ async getOutput() { return this.getAllLogsAsString(); } /** * Returns the state of the session. * * @return state of the session */ async getState() { return FFmpegKitReactNativeModule.abstractSessionGetState(this.getSessionId()); } /** * Returns the return code for this session. Note that return code is only set for sessions * that end with COMPLETED state. If a session is not started, still running or failed then * this method returns undefined. * * @return the return code for this session if the session is COMPLETED, undefined if session is * not started, still running or failed */ async getReturnCode() { const returnCodeValue = await FFmpegKitReactNativeModule.abstractSessionGetReturnCode(this.getSessionId()); if (returnCodeValue === undefined) { return undefined; } else { return new ReturnCode(returnCodeValue); } } /** * Returns the stack trace of the exception received while executing this session. *

* The stack trace is only set for sessions that end with FAILED state. For sessions that has * COMPLETED state this method returns undefined. * * @return stack trace of the exception received while executing this session, undefined if session * is not started, still running or completed */ getFailStackTrace() { return FFmpegKitReactNativeModule.abstractSessionGetFailStackTrace(this.getSessionId()); } /** * Returns session specific log redirection strategy. * * @return session specific log redirection strategy */ getLogRedirectionStrategy() { return this.#logRedirectionStrategy; } /** * Returns whether there are still asynchronous messages being transmitted for this * session or not. * * @return true if there are still asynchronous messages being transmitted, false * otherwise */ thereAreAsynchronousMessagesInTransmit() { return FFmpegKitReactNativeModule.abstractSessionThereAreAsynchronousMessagesInTransmit(this.getSessionId()); } /** * Returns whether it is an FFmpeg session or not. * * @return true if it is an FFmpeg session, false otherwise */ isFFmpeg() { return false; } /** * Returns whether it is an FFprobe session or not. * * @return true if it is an FFprobe session, false otherwise */ isFFprobe() { return false; } /** * Returns whether it is a MediaInformation session or not. * * @return true if it is a MediaInformation session, false otherwise */ isMediaInformation() { return false; } /** * Cancels running the session. */ cancel() { const sessionId = this.getSessionId(); if (sessionId === undefined) { return FFmpegKitReactNativeModule.cancel(); } else { return FFmpegKitReactNativeModule.cancelSession(sessionId); } } } /** * Detects the running architecture. */ export class ArchDetect { /** * Returns architecture name loaded. * * @return architecture name loaded */ static async getArch() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getArch(); } } /** *

Main class to run FFmpeg commands. */ export class FFmpegKit { /** *

Synchronously executes FFmpeg command provided. Space character is used to split the command * into arguments. You can use single or double quote characters to specify arguments inside your command. * * @param command FFmpeg command * @return FFmpeg session created for this execution */ static async execute(command) { return FFmpegKit.executeWithArguments(FFmpegKitConfig.parseArguments(command)); } /** *

Synchronously executes FFmpeg with arguments provided. * * @param commandArguments FFmpeg command options/arguments as string array * @return FFmpeg session created for this execution */ static async executeWithArguments(commandArguments) { let session = await FFmpegSession.create(commandArguments, undefined, undefined, undefined); await FFmpegKitConfig.ffmpegExecute(session); return session; } /** *

Starts an asynchronous FFmpeg execution for the given command. Space character is used to split the command * into arguments. You can use single or double quote characters to specify arguments inside your command. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * FFmpegSessionCompleteCallback if you want to be notified about the result. * * @param command FFmpeg command * @param completeCallback callback that will be called when the execution has completed * @param logCallback callback that will receive logs * @param statisticsCallback callback that will receive statistics * @return FFmpeg session created for this execution */ static async executeAsync(command, completeCallback, logCallback, statisticsCallback) { return FFmpegKit.executeWithArgumentsAsync(FFmpegKitConfig.parseArguments(command), completeCallback, logCallback, statisticsCallback); } /** *

Starts an asynchronous FFmpeg execution with arguments provided. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * FFmpegSessionCompleteCallback if you want to be notified about the result. * * @param commandArguments FFmpeg command options/arguments as string array * @param completeCallback callback that will be called when the execution has completed * @param logCallback callback that will receive logs * @param statisticsCallback callback that will receive statistics * @return FFmpeg session created for this execution */ static async executeWithArgumentsAsync(commandArguments, completeCallback, logCallback, statisticsCallback) { let session = await FFmpegSession.create(commandArguments, completeCallback, logCallback, statisticsCallback); await FFmpegKitConfig.asyncFFmpegExecute(session); return session; } /** *

Cancels the session specified with sessionId. * *

This method does not wait for termination to complete and returns immediately. * * @param sessionId id of the session that will be cancelled */ static async cancel(sessionId) { await FFmpegKitConfig.init(); if (sessionId === undefined) { return FFmpegKitReactNativeModule.cancel(); } else { return FFmpegKitReactNativeModule.cancelSession(sessionId); } } /** *

Lists all FFmpeg sessions in the session history. * * @return all FFmpeg sessions in the session history */ static async listSessions() { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getFFmpegSessions(); return sessionArray.map(FFmpegKitFactory.mapToSession); } } /** *

Configuration class of FFmpegKit library. */ export class FFmpegKitConfig { static #globalLogRedirectionStrategy = LogRedirectionStrategy.PRINT_LOGS_WHEN_NO_CALLBACKS_DEFINED; /** * Initializes the library asynchronously. */ static async init() { await FFmpegKitInitializer.initialize(); } /** *

Enables log and statistics redirection. * *

When redirection is enabled FFmpeg/FFprobe logs are redirected to console and sessions * collect log and statistics entries for the executions. It is possible to define global or * session specific log/statistics callbacks as well. * *

Note that redirection is enabled by default. If you do not want to use its functionality * please use {@link #disableRedirection()} to disable it. */ static async enableRedirection() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.enableRedirection(); } /** *

Disables log and statistics redirection. * *

When redirection is disabled logs are printed to stderr, all logs and statistics * callbacks are disabled and FFprobe's getMediaInformation methods * do not work. */ static async disableRedirection() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.disableRedirection(); } /** *

Sets and overrides fontconfig configuration directory. * * @param path directory that contains fontconfig configuration (fonts.conf) * @return zero on success, non-zero on error */ static async setFontconfigConfigurationPath(path) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.setFontconfigConfigurationPath(path); } /** *

Registers the fonts inside the given path, so they become available to use in FFmpeg * filters. * *

Note that you need to use a package with fontconfig inside to be * able to use fonts in FFmpeg. * * @param fontDirectoryPath directory that contains fonts (.ttf and .otf files) * @param fontNameMapping custom font name mappings, useful to access your fonts with more * friendly names */ static async setFontDirectory(fontDirectoryPath, fontNameMapping) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.setFontDirectory(fontDirectoryPath, fontNameMapping); } /** *

Registers the fonts inside the given list of font directories, so they become available * to use in FFmpeg filters. * *

Note that you need to use a package with fontconfig inside to be * able to use fonts in FFmpeg. * * @param fontDirectoryList list of directories that contain fonts (.ttf and .otf files) * @param fontNameMapping custom font name mappings, useful to access your fonts with more * friendly names */ static async setFontDirectoryList(fontDirectoryList, fontNameMapping) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.setFontDirectoryList(fontDirectoryList, fontNameMapping); } /** *

Creates a new named pipe to use in FFmpeg operations. * *

Please note that creator is responsible of closing created pipes. * * @return the full path of the named pipe */ static async registerNewFFmpegPipe() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.registerNewFFmpegPipe(); } /** *

Closes a previously created FFmpeg pipe. * * @param ffmpegPipePath full path of the FFmpeg pipe */ static async closeFFmpegPipe(ffmpegPipePath) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.closeFFmpegPipe(ffmpegPipePath); } /** *

Returns the version of FFmpeg bundled within FFmpegKit library. * * @return the version of FFmpeg */ static async getFFmpegVersion() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getFFmpegVersion(); } /** *

Returns FFmpegKit ReactNative library version. * * @return FFmpegKit version */ static async getVersion() { return new Promise((resolve) => resolve(FFmpegKitFactory.getVersion())); } /** *

Returns whether FFmpegKit release is a Long Term Release or not. * * @return true/yes or false/no */ static async isLTSBuild() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.isLTSBuild(); } /** *

Returns FFmpegKit native library build date. * * @return FFmpegKit native library build date */ static async getBuildDate() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getBuildDate(); } /** *

Sets an environment variable. * * @param variableName environment variable name * @param variableValue environment variable value * @return zero on success, non-zero on error */ static async setEnvironmentVariable(variableName, variableValue) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.setEnvironmentVariable(variableName, variableValue); } /** *

Registers a new ignored signal. Ignored signals are not handled by FFmpegKit * library. * * @param signal signal to be ignored */ static async ignoreSignal(signal) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.ignoreSignal(signal); } /** *

Synchronously executes the FFmpeg session provided. * * @param ffmpegSession FFmpeg session which includes command options/arguments */ static async ffmpegExecute(ffmpegSession) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.ffmpegSessionExecute(ffmpegSession.getSessionId()); } /** *

Synchronously executes the FFprobe session provided. * * @param ffprobeSession FFprobe session which includes command options/arguments */ static async ffprobeExecute(ffprobeSession) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.ffprobeSessionExecute(ffprobeSession.getSessionId()); } /** *

Synchronously executes the media information session provided. * * @param mediaInformationSession media information session which includes command options/arguments * @param waitTimeout max time to wait until media information is transmitted */ static async getMediaInformationExecute(mediaInformationSession, waitTimeout) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.mediaInformationSessionExecute(mediaInformationSession.getSessionId(), FFmpegKitFactory.optionalNumericParameter(waitTimeout)); } /** *

Starts an asynchronous FFmpeg execution for the given session. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * FFmpegSessionCompleteCallback if you want to be notified about the result. * * @param ffmpegSession FFmpeg session which includes command options/arguments */ static async asyncFFmpegExecute(ffmpegSession) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.asyncFFmpegSessionExecute(ffmpegSession.getSessionId()); } /** *

Starts an asynchronous FFprobe execution for the given session. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * FFprobeSessionCompleteCallback if you want to be notified about the result. * * @param ffprobeSession FFprobe session which includes command options/arguments */ static async asyncFFprobeExecute(ffprobeSession) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.asyncFFprobeSessionExecute(ffprobeSession.getSessionId()); } /** *

Starts an asynchronous FFprobe execution for the given media information session. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * MediaInformationSessionCompleteCallback if you want to be notified about the result. * * @param mediaInformationSession media information session which includes command options/arguments * @param waitTimeout max time to wait until media information is transmitted */ static async asyncGetMediaInformationExecute(mediaInformationSession, waitTimeout) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.asyncMediaInformationSessionExecute(mediaInformationSession.getSessionId(), FFmpegKitFactory.optionalNumericParameter(waitTimeout)); } /** *

Sets a global callback to redirect FFmpeg/FFprobe logs. * * @param logCallback log callback or undefined to disable a previously defined * callback */ static enableLogCallback(logCallback) { FFmpegKitFactory.setGlobalLogCallback(logCallback); } /** *

Sets a global callback to redirect FFmpeg statistics. * * @param statisticsCallback statistics callback or undefined to disable a previously * defined callback */ static enableStatisticsCallback(statisticsCallback) { FFmpegKitFactory.setGlobalStatisticsCallback(statisticsCallback); } /** *

Sets a global FFmpegSessionCompleteCallback to receive execution results for FFmpeg sessions. * * @param ffmpegSessionCompleteCallback complete callback or undefined to disable a previously defined callback */ static enableFFmpegSessionCompleteCallback(ffmpegSessionCompleteCallback) { FFmpegKitFactory.setGlobalFFmpegSessionCompleteCallback(ffmpegSessionCompleteCallback); } /** *

Returns the global FFmpegSessionCompleteCallback set. * * @return global FFmpegSessionCompleteCallback or undefined if it is not set */ static getFFmpegSessionCompleteCallback() { return FFmpegKitFactory.getGlobalFFmpegSessionCompleteCallback(); } /** *

Sets a global FFprobeSessionCompleteCallback to receive execution results for FFprobe sessions. * * @param ffprobeSessionCompleteCallback complete callback or undefined to disable a previously defined callback */ static enableFFprobeSessionCompleteCallback(ffprobeSessionCompleteCallback) { FFmpegKitFactory.setGlobalFFprobeSessionCompleteCallback(ffprobeSessionCompleteCallback); } /** *

Returns the global FFprobeSessionCompleteCallback set. * * @return global FFprobeSessionCompleteCallback or undefined if it is not set */ static getFFprobeSessionCompleteCallback() { return FFmpegKitFactory.getGlobalFFprobeSessionCompleteCallback(); } /** *

Sets a global MediaInformationSessionCompleteCallback to receive execution results for MediaInformation sessions. * * @param mediaInformationSessionCompleteCallback complete callback or undefined to disable a previously defined * callback */ static enableMediaInformationSessionCompleteCallback(mediaInformationSessionCompleteCallback) { FFmpegKitFactory.setGlobalMediaInformationSessionCompleteCallback(mediaInformationSessionCompleteCallback); } /** *

Returns the global MediaInformationSessionCompleteCallback set. * * @return global MediaInformationSessionCompleteCallback or undefined if it is not set */ static getMediaInformationSessionCompleteCallback() { return FFmpegKitFactory.getGlobalMediaInformationSessionCompleteCallback(); } /** * Returns the current log level. * * @return current log level */ static getLogLevel() { return FFmpegKitFactory.getLogLevel(); } /** * Sets the log level. * * @param level new log level */ static async setLogLevel(level) { await FFmpegKitConfig.init(); FFmpegKitFactory.setLogLevel(level); return FFmpegKitReactNativeModule.setLogLevel(level); } /** *

Converts the given Structured Access Framework Uri into an input url that can be used in FFmpeg * and FFprobe commands. * *

Note that this method is Android only. It will fail if called on other platforms. It also requires * API Level ≥ 19. On older API levels it returns an empty url. * * @param uriString SAF uri ("content:…") * @return input url that can be passed to FFmpegKit or FFprobeKit */ static async getSafParameterForRead(uriString) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getSafParameter(uriString, "r"); } /** *

Converts the given Structured Access Framework Uri into an output url that can be used in FFmpeg * and FFprobe commands. * *

Note that this method is Android only. It will fail if called on other platforms. It also requires * API Level ≥ 19. On older API levels it returns an empty url. * * @param uriString SAF uri ("content:…") * @return output url that can be passed to FFmpegKit or FFprobeKit */ static async getSafParameterForWrite(uriString) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getSafParameter(uriString, "w"); } /** *

Converts the given Structured Access Framework Uri into an saf protocol url opened with the given open mode. * *

Note that this method is Android only. It will fail if called on other platforms. It also requires * API Level ≥ 19. On older API levels it returns an empty url. * * @param uriString SAF uri ("content:…") * @param openMode file mode to use as defined in Android Structured Access Framework documentation * @return saf protocol url that can be passed to FFmpegKit or FFprobeKit */ static async getSafParameter(uriString, openMode) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getSafParameter(uriString, openMode); } /** * Returns the session history size. * * @return session history size */ static async getSessionHistorySize() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getSessionHistorySize(); } /** * Sets the session history size. * * @param sessionHistorySize session history size, should be smaller than 1000 */ static async setSessionHistorySize(sessionHistorySize) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.setSessionHistorySize(sessionHistorySize); } /** * Returns the session specified with sessionId from the session history. * * @param sessionId session identifier * @return session specified with sessionId or undefined if it is not found in the history */ static async getSession(sessionId) { await FFmpegKitConfig.init(); if (sessionId === undefined) { return undefined; } else { const sessionMap = await FFmpegKitReactNativeModule.getSession(sessionId); return FFmpegKitFactory.mapToSession(sessionMap); } } /** * Returns the last session created from the session history. * * @return the last session created or undefined if session history is empty */ static async getLastSession() { await FFmpegKitConfig.init(); const sessionMap = await FFmpegKitReactNativeModule.getLastSession(); return FFmpegKitFactory.mapToSession(sessionMap); } /** * Returns the last session completed from the session history. * * @return the last session completed. If there are no completed sessions in the history this * method will return undefined */ static async getLastCompletedSession() { await FFmpegKitConfig.init(); const sessionMap = await FFmpegKitReactNativeModule.getLastCompletedSession(); return FFmpegKitFactory.mapToSession(sessionMap); } /** *

Returns all sessions in the session history. * * @return all sessions in the session history */ static async getSessions() { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getSessions(); return sessionArray.map(FFmpegKitFactory.mapToSession); } /** *

Clears all, including ongoing, sessions in the session history. *

Note that callbacks cannot be triggered for deleted sessions. */ static async clearSessions() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.clearSessions(); } /** *

Returns all FFmpeg sessions in the session history. * * @return all FFmpeg sessions in the session history */ static async getFFmpegSessions() { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getFFmpegSessions(); return sessionArray.map(FFmpegKitFactory.mapToSession); } /** *

Returns all FFprobe sessions in the session history. * * @return all FFprobe sessions in the session history */ static async getFFprobeSessions() { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getFFprobeSessions(); return sessionArray.map(FFmpegKitFactory.mapToSession); } /** *

Returns all MediaInformation sessions in the session history. * * @return all MediaInformation sessions in the session history */ static async getMediaInformationSessions() { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getMediaInformationSessions(); return sessionArray.map(FFmpegKitFactory.mapToSession); } /** *

Returns sessions that have the given state. * * @param state session state * @return sessions that have the given state from the session history */ static async getSessionsByState(state) { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getSessionsByState(state); return sessionArray.map(FFmpegKitFactory.mapToSession); } /** * Returns the active log redirection strategy. * * @return log redirection strategy */ static getLogRedirectionStrategy() { return this.#globalLogRedirectionStrategy; } /** *

Sets the log redirection strategy. * * @param logRedirectionStrategy log redirection strategy */ static setLogRedirectionStrategy(logRedirectionStrategy) { this.#globalLogRedirectionStrategy = logRedirectionStrategy; } /** *

Returns the number of messages that are not transmitted to the ReactNative callbacks yet for * this session. * * @param sessionId id of the session * @return number of messages that are not transmitted to the ReactNative callbacks yet for * this session */ static async messagesInTransmit(sessionId) { await FFmpegKitConfig.init(); const sessionMap = await FFmpegKitReactNativeModule.messagesInTransmit(sessionId); return FFmpegKitFactory.mapToSession(sessionMap); } /** * Returns the string representation of the SessionState provided. * * @param state session state instance * @returns string representation of the SessionState provided */ static sessionStateToString(state) { switch (state) { case SessionState.CREATED: return "CREATED"; case SessionState.RUNNING: return "RUNNING"; case SessionState.FAILED: return "FAILED"; case SessionState.COMPLETED: return "COMPLETED"; default: return ""; } } /** *

Parses the given command into arguments. Uses space character to split the arguments. * Supports single and double quote characters. * * @param command string command * @return array of arguments */ static parseArguments(command) { let argumentList = []; let currentArgument = ""; let singleQuoteStarted = 0; let doubleQuoteStarted = 0; for (let i = 0; i < command.length; i++) { let previousChar; if (i > 0) { previousChar = command.charAt(i - 1); } else { previousChar = null; } let currentChar = command.charAt(i); if (currentChar === ' ') { if (singleQuoteStarted === 1 || doubleQuoteStarted === 1) { currentArgument += currentChar; } else if (currentArgument.length > 0) { argumentList.push(currentArgument); currentArgument = ""; } } else if (currentChar === '\'' && (previousChar == null || previousChar !== '\\')) { if (singleQuoteStarted === 1) { singleQuoteStarted = 0; } else if (doubleQuoteStarted === 1) { currentArgument += currentChar; } else { singleQuoteStarted = 1; } } else if (currentChar === '\"' && (previousChar == null || previousChar !== '\\')) { if (doubleQuoteStarted === 1) { doubleQuoteStarted = 0; } else if (singleQuoteStarted === 1) { currentArgument += currentChar; } else { doubleQuoteStarted = 1; } } else { currentArgument += currentChar; } } if (currentArgument.length > 0) { argumentList.push(currentArgument); } return argumentList; } /** *

Concatenates arguments into a string adding a space character between two arguments. * * @param commandArguments arguments * @return concatenated string containing all arguments */ static argumentsToString(commandArguments) { if (commandArguments === undefined) { return 'undefined'; } let command = ''; function appendArgument(value, index) { if (index > 0) { command += ' '; } command += value; } commandArguments.forEach(appendArgument); return command; } // THE FOLLOWING TWO METHODS ARE REACT-NATIVE SPECIFIC /** * Enables logs. */ static async enableLogs() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.enableLogs(); } /** * Disable logs. */ static async disableLogs() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.disableLogs(); } /** * Enables statistics. */ static async enableStatistics() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.enableStatistics(); } /** * Disables statistics. */ static async disableStatistics() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.disableStatistics(); } /** * Returns the platform name the library is loaded on. */ static async getPlatform() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getPlatform(); } /** * Writes the given file to a pipe. * * @param inputPath input file path * @param pipePath pipe path * @returns zero on success, non-zero on error */ static async writeToPipe(inputPath, pipePath) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.writeToPipe(inputPath, pipePath); } /** *

Displays the native file dialog to select a file in read mode. If a file is selected then this * method returns the Structured Access Framework Uri for that file. * *

Note that this method is Android only. It will fail if called on other platforms. * * @param type specifies a mime type for the file dialog * @param extraTypes additional mime types * @returns Structured Access Framework Uri ("content:…") of the file selected or undefined * if no files are selected */ static async selectDocumentForRead(type, extraTypes) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.selectDocument(false, undefined, type, extraTypes); } /** *

Displays the native file dialog to select a file in write mode. If a file is selected then this * method returns the Structured Access Framework Uri for that file. * *

Note that this method is Android only. It will fail if called on other platforms. * * @param title file name * @param type specifies a mime type for the file dialog * @param extraTypes additional mime types * @returns Structured Access Framework Uri ("content:…") of the file selected or undefined * if no files are selected */ static async selectDocumentForWrite(title, type, extraTypes) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.selectDocument(true, title, type, extraTypes); } } class FFmpegKitFactory { static #ffmpegSessionCompleteCallback = undefined; static #ffprobeSessionCompleteCallback = undefined; static #mediaInformationSessionCompleteCallback = undefined; static #logCallback = undefined; static #statisticsCallback = undefined; static #activeLogLevel = undefined; static mapToStatistics(statisticsMap) { if (statisticsMap !== undefined) { return new Statistics(statisticsMap.sessionId, statisticsMap.videoFrameNumber, statisticsMap.videoFps, statisticsMap.videoQuality, statisticsMap.size, statisticsMap.time, statisticsMap.bitrate, statisticsMap.speed); } else { return undefined; } } static mapToLog(logMap) { if (logMap !== undefined) { return new Log(logMap.sessionId, logMap.level, logMap.message) } else { return undefined; } } static mapToSession(sessionMap) { if (sessionMap !== undefined) { switch (sessionMap.type) { case 2: return FFprobeSession.fromMap(sessionMap); case 3: return MediaInformationSession.fromMap(sessionMap); case 1: default: return FFmpegSession.fromMap(sessionMap); } } else { return undefined; } } static getVersion() { return "4.5.1"; } static getLogRedirectionStrategy(sessionId) { return logRedirectionStrategyMap.get(sessionId); } static setLogRedirectionStrategy(sessionId, logRedirectionStrategy) { logRedirectionStrategyMap.set(sessionId, logRedirectionStrategy); } static getLogCallback(sessionId) { return logCallbackMap.get(sessionId); } static setLogCallback(sessionId, logCallback) { if (logCallback !== undefined) { logCallbackMap.set(sessionId, logCallback); } } static getGlobalLogCallback() { return this.#logCallback; } static setGlobalLogCallback(logCallback) { this.#logCallback = logCallback; } static getStatisticsCallback(sessionId) { return statisticsCallbackMap.get(sessionId); } static setStatisticsCallback(sessionId, statisticsCallback) { if (statisticsCallback !== undefined) { statisticsCallbackMap.set(sessionId, statisticsCallback); } } static getGlobalStatisticsCallback() { return this.#statisticsCallback; } static setGlobalStatisticsCallback(statisticsCallback) { this.#statisticsCallback = statisticsCallback; } static getFFmpegSessionCompleteCallback(sessionId) { return ffmpegSessionCompleteCallbackMap.get(sessionId); } static setFFmpegSessionCompleteCallback(sessionId, completeCallback) { if (completeCallback !== undefined) { ffmpegSessionCompleteCallbackMap.set(sessionId, completeCallback); } } static getGlobalFFmpegSessionCompleteCallback() { return this.#ffmpegSessionCompleteCallback; } static setGlobalFFmpegSessionCompleteCallback(completeCallback) { this.#ffmpegSessionCompleteCallback = completeCallback; } static getFFprobeSessionCompleteCallback(sessionId) { return ffprobeSessionCompleteCallbackMap.get(sessionId); } static setFFprobeSessionCompleteCallback(sessionId, completeCallback) { if (completeCallback !== undefined) { ffprobeSessionCompleteCallbackMap.set(sessionId, completeCallback); } } static getGlobalFFprobeSessionCompleteCallback() { return this.#ffprobeSessionCompleteCallback; } static setGlobalFFprobeSessionCompleteCallback(completeCallback) { this.#ffprobeSessionCompleteCallback = completeCallback; } static getMediaInformationSessionCompleteCallback(sessionId) { return mediaInformationSessionCompleteCallbackMap.get(sessionId); } static setMediaInformationSessionCompleteCallback(sessionId, completeCallback) { if (completeCallback !== undefined) { mediaInformationSessionCompleteCallbackMap.set(sessionId, completeCallback); } } static getGlobalMediaInformationSessionCompleteCallback() { return this.#mediaInformationSessionCompleteCallback; } static setGlobalMediaInformationSessionCompleteCallback(completeCallback) { this.#mediaInformationSessionCompleteCallback = completeCallback; } static setLogLevel(logLevel) { this.#activeLogLevel = logLevel; } static getLogLevel() { return this.#activeLogLevel; } static optionalNumericParameter(value) { return value ?? -1; } static validDate(time) { if (time === undefined || time === null || time <= 0) { return undefined; } else { return new Date(time); } } } class FFmpegKitInitializer { static #initialized = false; static #eventEmitter = new FFmpegKitReactNativeEventEmitter(); static processLogCallbackEvent(event) { const log = FFmpegKitFactory.mapToLog(event) const sessionId = event.sessionId; const level = event.level; const text = event.message; const activeLogLevel = FFmpegKitConfig.getLogLevel(); let globalCallbackDefined = false; let sessionCallbackDefined = false; let activeLogRedirectionStrategy = FFmpegKitConfig.getLogRedirectionStrategy(); // AV_LOG_STDERR logs are always redirected if ((activeLogLevel === Level.AV_LOG_QUIET && level !== Level.AV_LOG_STDERR) || level > activeLogLevel) { // LOG NEITHER PRINTED NOR FORWARDED return; } if (FFmpegKitFactory.getLogRedirectionStrategy(sessionId) !== undefined) { activeLogRedirectionStrategy = FFmpegKitFactory.getLogRedirectionStrategy(sessionId); } let activeLogCallback = FFmpegKitFactory.getLogCallback(sessionId); if (activeLogCallback !== undefined) { sessionCallbackDefined = true; try { // NOTIFY SESSION CALLBACK DEFINED activeLogCallback(log); } catch (err) { console.log("Exception thrown inside session log callback.", err.stack); } } let globalLogCallbackFunction = FFmpegKitFactory.getGlobalLogCallback(); if (globalLogCallbackFunction !== undefined) { globalCallbackDefined = true; try { // NOTIFY GLOBAL CALLBACK DEFINED globalLogCallbackFunction(log); } catch (err) { console.log("Exception thrown inside global log callback.", err.stack); } } // EXECUTE THE LOG STRATEGY switch (activeLogRedirectionStrategy) { case LogRedirectionStrategy.NEVER_PRINT_LOGS: { return; } case LogRedirectionStrategy.PRINT_LOGS_WHEN_GLOBAL_CALLBACK_NOT_DEFINED: { if (globalCallbackDefined) { return; } } break; case LogRedirectionStrategy.PRINT_LOGS_WHEN_SESSION_CALLBACK_NOT_DEFINED: { if (sessionCallbackDefined) { return; } } break; case LogRedirectionStrategy.PRINT_LOGS_WHEN_NO_CALLBACKS_DEFINED: { if (globalCallbackDefined || sessionCallbackDefined) { return; } } break; case LogRedirectionStrategy.ALWAYS_PRINT_LOGS: { } break; } // PRINT LOGS switch (level) { case Level.AV_LOG_QUIET: { // PRINT NO OUTPUT } break; default: { console.log(text); } } } static processStatisticsCallbackEvent(event) { let statistics = FFmpegKitFactory.mapToStatistics(event); let sessionId = event.sessionId; let activeStatisticsCallback = FFmpegKitFactory.getStatisticsCallback(sessionId); if (activeStatisticsCallback !== undefined) { try { // NOTIFY SESSION CALLBACK DEFINED activeStatisticsCallback(statistics); } catch (err) { console.log("Exception thrown inside session statistics callback.", err.stack); } } let globalStatisticsCallbackFunction = FFmpegKitFactory.getGlobalStatisticsCallback(); if (globalStatisticsCallbackFunction !== undefined) { try { // NOTIFY GLOBAL CALLBACK DEFINED globalStatisticsCallbackFunction(statistics); } catch (err) { console.log("Exception thrown inside global statistics callback.", err.stack); } } } static processCompleteCallbackEvent(event) { if (event !== undefined) { let sessionId = event.sessionId; FFmpegKitConfig.getSession(sessionId).then(session => { if (session !== undefined) { if (session.getCompleteCallback() !== undefined) { try { // NOTIFY SESSION CALLBACK DEFINED session.getCompleteCallback()(session); } catch (err) { console.log("Exception thrown inside session complete callback.", err.stack); } } if (session.isFFmpeg()) { let globalFFmpegSessionCompleteCallback = FFmpegKitFactory.getGlobalFFmpegSessionCompleteCallback(); if (globalFFmpegSessionCompleteCallback !== undefined) { try { // NOTIFY GLOBAL CALLBACK DEFINED globalFFmpegSessionCompleteCallback(session); } catch (err) { console.log("Exception thrown inside global complete callback.", err.stack); } } } else if (session.isFFprobe()) { let globalFFprobeSessionCompleteCallback = FFmpegKitFactory.getGlobalFFprobeSessionCompleteCallback(); if (globalFFprobeSessionCompleteCallback !== undefined) { try { // NOTIFY GLOBAL CALLBACK DEFINED globalFFprobeSessionCompleteCallback(session); } catch (err) { console.log("Exception thrown inside global complete callback.", err.stack); } } } else if (session.isMediaInformation()) { let globalMediaInformationSessionCompleteCallback = FFmpegKitFactory.getGlobalMediaInformationSessionCompleteCallback(); if (globalMediaInformationSessionCompleteCallback !== undefined) { try { // NOTIFY GLOBAL CALLBACK DEFINED globalMediaInformationSessionCompleteCallback(session); } catch (err) { console.log("Exception thrown inside global complete callback.", err.stack); } } } } }); } } static async initialize() { if (this.#initialized) { return; } else { this.#initialized = true; } console.log("Loading ffmpeg-kit-react-native."); this.#eventEmitter.addListener(eventLogCallbackEvent, FFmpegKitInitializer.processLogCallbackEvent); this.#eventEmitter.addListener(eventStatisticsCallbackEvent, FFmpegKitInitializer.processStatisticsCallbackEvent); this.#eventEmitter.addListener(eventCompleteCallbackEvent, FFmpegKitInitializer.processCompleteCallbackEvent); FFmpegKitFactory.setLogLevel(await FFmpegKitReactNativeModule.getLogLevel()); const version = FFmpegKitFactory.getVersion(); const platform = await FFmpegKitConfig.getPlatform(); const arch = await ArchDetect.getArch(); const packageName = await Packages.getPackageName(); await FFmpegKitConfig.enableRedirection(); const isLTSPostfix = (await FFmpegKitConfig.isLTSBuild()) ? "-lts" : ""; console.log(`Loaded ffmpeg-kit-react-native-${platform}-${packageName}-${arch}-${version}${isLTSPostfix}.`); } } /** *

An FFmpeg session. */ export class FFmpegSession extends AbstractSession { /** * Creates an empty FFmpeg session. */ constructor() { super(); } /** * Creates a new FFmpeg session. * * @param argumentsArray FFmpeg command arguments * @param completeCallback callback that will be called when the execution has completed * @param logCallback callback that will receive logs * @param statisticsCallback callback that will receive statistics * @param logRedirectionStrategy defines how logs will be redirected * @returns FFmpeg session created */ static async create(argumentsArray, completeCallback, logCallback, statisticsCallback, logRedirectionStrategy) { const session = await AbstractSession.createFFmpegSession(argumentsArray, logRedirectionStrategy); const sessionId = session.getSessionId(); FFmpegKitFactory.setFFmpegSessionCompleteCallback(sessionId, completeCallback); FFmpegKitFactory.setLogCallback(sessionId, logCallback); FFmpegKitFactory.setStatisticsCallback(sessionId, statisticsCallback); return session; } /** * Creates a new FFmpeg session from the given map. * * @param sessionMap map that includes session fields as map keys * @returns FFmpeg session created */ static fromMap(sessionMap) { return AbstractSession.createFFmpegSessionFromMap(sessionMap); } /** * Returns the session specific statistics callback. * * @return session specific statistics callback */ getStatisticsCallback() { return FFmpegKitFactory.getStatisticsCallback(this.getSessionId()); } /** * Returns the session specific complete callback. * * @return session specific complete callback */ getCompleteCallback() { return FFmpegKitFactory.getFFmpegSessionCompleteCallback(this.getSessionId()); } /** * Returns all statistics entries generated for this session. If there are asynchronous * messages that are not delivered yet, this method waits for them until the given timeout. * * @param waitTimeout wait timeout for asynchronous messages in milliseconds * @return list of statistics entries generated for this session */ async getAllStatistics(waitTimeout) { await FFmpegKitConfig.init(); const allStatistics = await FFmpegKitReactNativeModule.ffmpegSessionGetAllStatistics(this.getSessionId(), FFmpegKitFactory.optionalNumericParameter(waitTimeout)); return allStatistics.map(FFmpegKitFactory.mapToStatistics); } /** * Returns all statistics entries delivered for this session. Note that if there are * asynchronous messages that are not delivered yet, this method will not wait for * them and will return immediately. * * @return list of statistics entries received for this session */ async getStatistics() { await FFmpegKitConfig.init(); const statistics = await FFmpegKitReactNativeModule.ffmpegSessionGetStatistics(this.getSessionId()); return statistics.map(FFmpegKitFactory.mapToStatistics); } /** * Returns the last received statistics entry. * * @return the last received statistics entry or undefined if there are not any statistics entries * received */ async getLastReceivedStatistics() { let statistics = await this.getStatistics(); if (statistics.length > 0) { return statistics[statistics.length - 1]; } else { return undefined; } } isFFmpeg() { return true; } isFFprobe() { return false; } isMediaInformation() { return false; } } /** *

Main class to run FFprobe commands. */ export class FFprobeKit { /** *

Synchronously executes FFprobe command provided. Space character is used to split the command * into arguments. You can use single or double quote characters to specify arguments inside your command. * * @param command FFprobe command * @return FFprobe session created for this execution */ static async execute(command) { return FFprobeKit.executeWithArguments(FFmpegKitConfig.parseArguments(command)); } /** *

Synchronously executes FFprobe with arguments provided. * * @param commandArguments FFprobe command options/arguments as string array * @return FFprobe session created for this execution */ static async executeWithArguments(commandArguments) { let session = await FFprobeSession.create(commandArguments, undefined, undefined); await FFmpegKitConfig.ffprobeExecute(session); return session; } /** *

Starts an asynchronous FFprobe execution for the given command. Space character is used to split the command * into arguments. You can use single or double quote characters to specify arguments inside your command. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * FFprobeSessionCompleteCallback if you want to be notified about the result. * * @param command FFprobe command * @param completeCallback callback that will be called when the execution has completed * @param logCallback callback that will receive logs * @return FFprobe session created for this execution */ static async executeAsync(command, completeCallback, logCallback) { return FFprobeKit.executeWithArgumentsAsync(FFmpegKitConfig.parseArguments(command), completeCallback, logCallback); } /** *

Starts an asynchronous FFprobe execution with arguments provided. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * FFprobeSessionCompleteCallback if you want to be notified about the result. * * @param commandArguments FFprobe command options/arguments as string array * @param completeCallback callback that will be called when the execution has completed * @param logCallback callback that will receive logs * @return FFprobe session created for this execution */ static async executeWithArgumentsAsync(commandArguments, completeCallback, logCallback) { let session = await FFprobeSession.create(commandArguments, completeCallback, logCallback); await FFmpegKitConfig.asyncFFprobeExecute(session); return session; } /** *

Extracts media information for the file specified with path. * * @param path path or uri of a media file * @param waitTimeout max time to wait until media information is transmitted * @return media information session created for this execution */ static async getMediaInformation(path, waitTimeout) { const commandArguments = ["-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-show_chapters", "-i", path]; return FFprobeKit.getMediaInformationFromCommandArguments(commandArguments, waitTimeout); } /** *

Extracts media information using the command provided. The command passed to * this method must generate the output in JSON format in order to successfully extract media information from it. * * @param command FFprobe command that prints media information for a file in JSON format * @param waitTimeout max time to wait until media information is transmitted * @return media information session created for this execution */ static async getMediaInformationFromCommand(command, waitTimeout) { return FFprobeKit.getMediaInformationFromCommandArguments(FFmpegKitConfig.parseArguments(command), waitTimeout); } /** *

Extracts media information using the command arguments provided. The command * passed to this method must generate the output in JSON format in order to successfully extract media information * from it. * * @param commandArguments FFprobe command arguments that prints media information for a file in JSON format * @param waitTimeout max time to wait until media information is transmitted * @return media information session created for this execution */ static async getMediaInformationFromCommandArguments(commandArguments, waitTimeout) { let session = await MediaInformationSession.create(commandArguments, undefined, undefined); await FFmpegKitConfig.getMediaInformationExecute(session, waitTimeout); const mediaInformation = await FFmpegKitReactNativeModule.getMediaInformation(session.getSessionId()); if (mediaInformation !== undefined && mediaInformation !== null) { session.setMediaInformation(new MediaInformation(mediaInformation)); } return session; } /** *

Starts an asynchronous FFprobe execution to extract the media information for the specified file. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * MediaInformationSessionCompleteCallback if you want to be notified about the result. * * @param path path or uri of a media file * @param completeCallback callback that will be notified when execution has completed * @param logCallback callback that will receive logs * @param waitTimeout max time to wait until media information is transmitted * @return media information session created for this execution */ static async getMediaInformationAsync(path, completeCallback, logCallback, waitTimeout) { const commandArguments = ["-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-show_chapters", "-i", path]; return FFprobeKit.getMediaInformationFromCommandArgumentsAsync(commandArguments, completeCallback, logCallback, waitTimeout); } /** *

Starts an asynchronous FFprobe execution to extract media information using a command. The command passed to * this method must generate the output in JSON format in order to successfully extract media information from it. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * MediaInformationSessionCompleteCallback if you want to be notified about the result. * * @param command FFprobe command that prints media information for a file in JSON format * @param completeCallback callback that will be notified when execution has completed * @param logCallback callback that will receive logs * @param waitTimeout max time to wait until media information is transmitted * @return media information session created for this execution */ static async getMediaInformationFromCommandAsync(command, completeCallback, logCallback, waitTimeout) { return FFprobeKit.getMediaInformationFromCommandArgumentsAsync(FFmpegKitConfig.parseArguments(command), completeCallback, logCallback, waitTimeout); } /** *

Starts an asynchronous FFprobe execution to extract media information using command arguments. The command * passed to this method must generate the output in JSON format in order to successfully extract media information * from it. * *

Note that this method returns immediately and does not wait the execution to complete. You must use an * MediaInformationSessionCompleteCallback if you want to be notified about the result. * * @param commandArguments FFprobe command arguments that prints media information for a file in JSON format * @param completeCallback callback that will be notified when execution has completed * @param logCallback callback that will receive logs * @param waitTimeout max time to wait until media information is transmitted * @return media information session created for this execution */ static async getMediaInformationFromCommandArgumentsAsync(commandArguments, completeCallback, logCallback, waitTimeout) { let session = await MediaInformationSession.create(commandArguments, completeCallback, logCallback); await FFmpegKitConfig.asyncGetMediaInformationExecute(session, waitTimeout); const mediaInformation = await FFmpegKitReactNativeModule.getMediaInformation(session.getSessionId()); if (mediaInformation !== undefined && mediaInformation !== null) { session.setMediaInformation(new MediaInformation(mediaInformation)); } return session; } /** *

Lists all FFprobe sessions in the session history. * * @return all FFprobe sessions in the session history */ static async listFFprobeSessions() { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getFFprobeSessions(); return sessionArray.map(FFmpegKitFactory.mapToSession); } /** *

Lists all MediaInformation sessions in the session history. * * @return all MediaInformation sessions in the session history */ static async listMediaInformationSessions() { await FFmpegKitConfig.init(); const sessionArray = await FFmpegKitReactNativeModule.getMediaInformationSessions(); return sessionArray.map(FFmpegKitFactory.mapToSession); } } /** *

An FFprobe session. */ export class FFprobeSession extends AbstractSession { /** * Creates an empty FFprobe session. */ constructor() { super(); } /** * Creates a new FFprobe session. * * @param argumentsArray FFprobe command arguments * @param completeCallback callback that will be called when the execution has completed * @param logCallback callback that will receive logs * @param logRedirectionStrategy defines how logs will be redirected * @returns FFprobe session created */ static async create(argumentsArray, completeCallback, logCallback, logRedirectionStrategy) { const session = await AbstractSession.createFFprobeSession(argumentsArray, logRedirectionStrategy); const sessionId = session.getSessionId(); FFmpegKitFactory.setFFprobeSessionCompleteCallback(sessionId, completeCallback); FFmpegKitFactory.setLogCallback(sessionId, logCallback); return session; } /** * Creates a new FFprobe session from the given map. * * @param sessionMap map that includes session fields as map keys * @returns FFprobe session created */ static fromMap(sessionMap) { return AbstractSession.createFFprobeSessionFromMap(sessionMap); } /** * Returns the session specific complete callback. * * @return session specific complete callback */ getCompleteCallback() { return FFmpegKitFactory.getFFprobeSessionCompleteCallback(this.getSessionId()); } isFFmpeg() { return false; } isFFprobe() { return true; } isMediaInformation() { return false; } } /** *

Defines log levels. */ export class Level { /** * This log level is used to specify logs printed to stderr by ffmpeg. * Logs that has this level are not filtered and always redirected. */ static AV_LOG_STDERR = -16; /** * Print no output. */ static AV_LOG_QUIET = -8; /** * Something went really wrong and we will crash now. */ static AV_LOG_PANIC = 0; /** * Something went wrong and recovery is not possible. * For example, no header was found for a format which depends * on headers or an illegal combination of parameters is used. */ static AV_LOG_FATAL = 8; /** * Something went wrong and cannot losslessly be recovered. * However, not all future data is affected. */ static AV_LOG_ERROR = 16; /** * Something somehow does not look correct. This may or may not * lead to problems. An example would be the use of '-vstrict -2'. */ static AV_LOG_WARNING = 24; /** * Standard information. */ static AV_LOG_INFO = 32; /** * Detailed information. */ static AV_LOG_VERBOSE = 40; /** * Stuff which is only useful for libav* developers. */ static AV_LOG_DEBUG = 48; /** * Extremely verbose debugging, useful for libav* development. */ static AV_LOG_TRACE = 56; /** * Returns log level string. * * @param level log level integer * @returns log level string */ static levelToString(level) { switch (level) { case Level.AV_LOG_TRACE: return "TRACE"; case Level.AV_LOG_DEBUG: return "DEBUG"; case Level.AV_LOG_VERBOSE: return "VERBOSE"; case Level.AV_LOG_INFO: return "INFO"; case Level.AV_LOG_WARNING: return "WARNING"; case Level.AV_LOG_ERROR: return "ERROR"; case Level.AV_LOG_FATAL: return "FATAL"; case Level.AV_LOG_PANIC: return "PANIC"; case Level.AV_LOG_STDERR: return "STDERR"; case Level.AV_LOG_QUIET: default: return ""; } } } /** *

Log entry for an FFmpegKit session. */ export class Log { #sessionId; #level; #message; constructor(sessionId, level, message) { this.#sessionId = sessionId; this.#level = level; this.#message = message; } getSessionId() { return this.#sessionId; } getLevel() { return this.#level; } getMessage() { return this.#message; } } /** * Media information class. */ export class MediaInformation { static KEY_MEDIA_PROPERTIES = "format"; static KEY_FILENAME = "filename"; static KEY_FORMAT = "format_name"; static KEY_FORMAT_LONG = "format_long_name"; static KEY_START_TIME = "start_time"; static KEY_DURATION = "duration"; static KEY_SIZE = "size"; static KEY_BIT_RATE = "bit_rate"; static KEY_TAGS = "tags"; #allProperties; constructor(properties) { this.#allProperties = properties; } /** * Returns file name. * * @return media file name */ getFilename() { return this.getStringProperty(MediaInformation.KEY_FILENAME); } /** * Returns format. * * @return media format */ getFormat() { return this.getStringProperty(MediaInformation.KEY_FORMAT); } /** * Returns long format. * * @return media long format */ getLongFormat() { return this.getStringProperty(MediaInformation.KEY_FORMAT_LONG); } /** * Returns duration. * * @return media duration in milliseconds */ getDuration() { return this.getStringProperty(MediaInformation.KEY_DURATION); } /** * Returns start time. * * @return media start time in milliseconds */ getStartTime() { return this.getStringProperty(MediaInformation.KEY_START_TIME); } /** * Returns size. * * @return media size in bytes */ getSize() { return this.getStringProperty(MediaInformation.KEY_SIZE); } /** * Returns bitrate. * * @return media bitrate in kb/s */ getBitrate() { return this.getStringProperty(MediaInformation.KEY_BIT_RATE); } /** * Returns all tags. * * @return tags dictionary */ getTags() { return this.getProperties(MediaInformation.KEY_TAGS); } /** * Returns the streams found as array. * * @returns StreamInformation array */ getStreams() { let list = []; let streamList; if (this.#allProperties !== undefined) { streamList = this.#allProperties.streams; } if (streamList !== undefined) { streamList.forEach((stream) => { list.push(new StreamInformation(stream)); }); } return list; } /** * Returns the chapters found as array. * * @returns Chapter array */ getChapters() { let list = []; let chapterList; if (this.#allProperties !== undefined) { chapterList = this.#allProperties.chapters; } if (chapterList !== undefined) { chapterList.forEach((chapter) => { list.push(new Chapter(chapter)); }); } return list; } /** * Returns the media property associated with the key. * * @param key property key * @return media property as string or undefined if the key is not found */ getStringProperty(key) { let mediaProperties = this.getMediaProperties(); if (mediaProperties !== undefined) { return mediaProperties[key]; } else { return undefined; } } /** * Returns the media property associated with the key. * * @param key property key * @return media property as number or undefined if the key is not found */ getNumberProperty(key) { let mediaProperties = this.getMediaProperties(); if (mediaProperties !== undefined) { return mediaProperties[key]; } else { return undefined; } } /** * Returns the media properties associated with the key. * * @param key properties key * @return media properties as an object or undefined if the key is not found */ getProperties(key) { let mediaProperties = this.getMediaProperties(); if (mediaProperties !== undefined) { return mediaProperties[key]; } else { return undefined; } } /** * Returns all media properties. * * @returns an object where media properties can be accessed by property names */ getMediaProperties() { if (this.#allProperties !== undefined) { return this.#allProperties.format; } else { return undefined; } } /** * Returns all properties found, including stream properties. * * @returns an object in which properties can be accessed by property names */ getAllProperties() { return this.#allProperties; } } /** * A parser that constructs {@link MediaInformation} from FFprobe's json output. */ export class MediaInformationJsonParser { /** * Extracts MediaInformation from the given FFprobe json output. Note that this * method does not fail as {@link #fromWithError(String)} does and returns undefined on error. * * @param ffprobeJsonOutput FFprobe json output * @return created {@link MediaInformation} instance of undefined if a parsing error occurs */ static async from(ffprobeJsonOutput) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.mediaInformationJsonParserFrom(ffprobeJsonOutput).map(properties => new MediaInformation(properties)); } /** * Extracts MediaInformation from the given FFprobe json output. * * @param ffprobeJsonOutput ffprobe json output * @return created {@link MediaInformation} instance */ static async fromWithError(ffprobeJsonOutput) { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.mediaInformationJsonParserFrom(ffprobeJsonOutput).map(properties => new MediaInformation(properties)); } } /** *

A custom FFprobe session, which produces a MediaInformation object using the * FFprobe output. */ export class MediaInformationSession extends AbstractSession { #mediaInformation; /** * Creates an empty MediaInformationSession. */ constructor() { super(); } /** * Creates a new MediaInformationSession session. * * @param argumentsArray FFprobe command arguments * @param completeCallback callback that will be called when the execution has completed * @param logCallback callback that will receive logs * @returns MediaInformationSession session created */ static async create(argumentsArray, completeCallback, logCallback) { const session = await AbstractSession.createMediaInformationSession(argumentsArray); const sessionId = session.getSessionId(); FFmpegKitFactory.setMediaInformationSessionCompleteCallback(sessionId, completeCallback); FFmpegKitFactory.setLogCallback(sessionId, logCallback); return session; } /** * Creates a new MediaInformationSession from the given map. * * @param sessionMap map that includes session fields as map keys * @returns MediaInformationSession created */ static fromMap(sessionMap) { return AbstractSession.createMediaInformationSessionFromMap(sessionMap); } /** * Returns the media information extracted in this session. * * @return media information extracted or undefined if the command failed or the output can not be * parsed */ getMediaInformation() { return this.#mediaInformation; } /** * Sets the media information extracted in this session. * * @param mediaInformation media information extracted */ setMediaInformation(mediaInformation) { this.#mediaInformation = mediaInformation; } /** * Returns the session specific complete callback. * * @return session specific complete callback */ getCompleteCallback() { return FFmpegKitFactory.getMediaInformationSessionCompleteCallback(this.getSessionId()); } isFFmpeg() { return false; } isFFprobe() { return false; } isMediaInformation() { return true; } } /** *

Helper class to extract binary package information. */ export class Packages { /** * Returns the FFmpegKit ReactNative binary package name. * * @return predicted FFmpegKit ReactNative binary package name */ static async getPackageName() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getPackageName(); } /** * Returns enabled external libraries by FFmpeg. * * @return enabled external libraries */ static async getExternalLibraries() { await FFmpegKitConfig.init(); return FFmpegKitReactNativeModule.getExternalLibraries(); } } export class ReturnCode { static SUCCESS = 0; static CANCEL = 255; #value; constructor(value) { this.#value = value; } static isSuccess(returnCode) { return (returnCode !== undefined && returnCode.getValue() === ReturnCode.SUCCESS); } static isCancel(returnCode) { return (returnCode !== undefined && returnCode.getValue() === ReturnCode.CANCEL); } getValue() { return this.#value; } isValueSuccess() { return (this.#value === ReturnCode.SUCCESS); } isValueError() { return ((this.#value !== ReturnCode.SUCCESS) && (this.#value !== ReturnCode.CANCEL)); } isValueCancel() { return (this.#value === ReturnCode.CANCEL); } toString() { return this.#value; } } /** *

Statistics entry for an FFmpeg execute session. */ export class Statistics { #sessionId; #videoFrameNumber; #videoFps; #videoQuality; #size; #time; #bitrate; #speed; constructor(sessionId, videoFrameNumber, videoFps, videoQuality, size, time, bitrate, speed) { this.#sessionId = sessionId; this.#videoFrameNumber = videoFrameNumber; this.#videoFps = videoFps; this.#videoQuality = videoQuality; this.#size = size; this.#time = time; this.#bitrate = bitrate; this.#speed = speed; } getSessionId() { return this.#sessionId; } setSessionId(sessionId) { this.#sessionId = sessionId; } getVideoFrameNumber() { return this.#videoFrameNumber; } setVideoFrameNumber(videoFrameNumber) { this.#videoFrameNumber = videoFrameNumber; } getVideoFps() { return this.#videoFps; } setVideoFps(videoFps) { this.#videoFps = videoFps; } getVideoQuality() { return this.#videoQuality; } setVideoQuality(videoQuality) { this.#videoQuality = videoQuality; } getSize() { return this.#size; } setSize(size) { this.#size = size; } getTime() { return this.#time; } setTime(time) { this.#time = time; } getBitrate() { return this.#bitrate; } setBitrate(bitrate) { this.#bitrate = bitrate; } getSpeed() { return this.#speed; } setSpeed(speed) { this.#speed = speed; } } /** * Stream information class. */ export class StreamInformation { static KEY_INDEX = "index"; static KEY_TYPE = "codec_type"; static KEY_CODEC = "codec_name"; static KEY_CODEC_LONG = "codec_long_name"; static KEY_FORMAT = "pix_fmt"; static KEY_WIDTH = "width"; static KEY_HEIGHT = "height"; static KEY_BIT_RATE = "bit_rate"; static KEY_SAMPLE_RATE = "sample_rate"; static KEY_SAMPLE_FORMAT = "sample_fmt"; static KEY_CHANNEL_LAYOUT = "channel_layout"; static KEY_SAMPLE_ASPECT_RATIO = "sample_aspect_ratio"; static KEY_DISPLAY_ASPECT_RATIO = "display_aspect_ratio"; static KEY_AVERAGE_FRAME_RATE = "avg_frame_rate"; static KEY_REAL_FRAME_RATE = "r_frame_rate"; static KEY_TIME_BASE = "time_base"; static KEY_CODEC_TIME_BASE = "codec_time_base"; static KEY_TAGS = "tags"; #allProperties; constructor(properties) { this.#allProperties = properties; } /** * Returns stream index. * * @return stream index, starting from zero */ getIndex() { return this.getNumberProperty(StreamInformation.KEY_INDEX); } /** * Returns stream type. * * @return stream type; audio or video */ getType() { return this.getStringProperty(StreamInformation.KEY_TYPE); } /** * Returns stream codec. * * @return stream codec */ getCodec() { return this.getStringProperty(StreamInformation.KEY_CODEC); } /** * Returns stream codec in long format. * * @return stream codec with additional profile and mode information */ getCodecLong() { return this.getStringProperty(StreamInformation.KEY_CODEC_LONG); } /** * Returns stream format. * * @return stream format */ getFormat() { return this.getStringProperty(StreamInformation.KEY_FORMAT); } /** * Returns width. * * @return width in pixels */ getWidth() { return this.getNumberProperty(StreamInformation.KEY_WIDTH); } /** * Returns height. * * @return height in pixels */ getHeight() { return this.getNumberProperty(StreamInformation.KEY_HEIGHT); } /** * Returns bitrate. * * @return bitrate in kb/s */ getBitrate() { return this.getStringProperty(StreamInformation.KEY_BIT_RATE); } /** * Returns sample rate. * * @return sample rate in hz */ getSampleRate() { return this.getStringProperty(StreamInformation.KEY_SAMPLE_RATE); } /** * Returns sample format. * * @return sample format */ getSampleFormat() { return this.getStringProperty(StreamInformation.KEY_SAMPLE_FORMAT); } /** * Returns channel layout. * * @return channel layout */ getChannelLayout() { return this.getStringProperty(StreamInformation.KEY_CHANNEL_LAYOUT); } /** * Returns sample aspect ratio. * * @return sample aspect ratio */ getSampleAspectRatio() { return this.getStringProperty(StreamInformation.KEY_SAMPLE_ASPECT_RATIO); } /** * Returns display aspect ratio. * * @return display aspect ratio */ getDisplayAspectRatio() { return this.getStringProperty(StreamInformation.KEY_DISPLAY_ASPECT_RATIO); } /** * Returns display aspect ratio. * * @return average frame rate in fps */ getAverageFrameRate() { return this.getStringProperty(StreamInformation.KEY_AVERAGE_FRAME_RATE); } /** * Returns real frame rate. * * @return real frame rate in tbr */ getRealFrameRate() { return this.getStringProperty(StreamInformation.KEY_REAL_FRAME_RATE); } /** * Returns time base. * * @return time base in tbn */ getTimeBase() { return this.getStringProperty(StreamInformation.KEY_TIME_BASE); } /** * Returns codec time base. * * @return codec time base in tbc */ getCodecTimeBase() { return this.getStringProperty(StreamInformation.KEY_CODEC_TIME_BASE); } /** * Returns all tags. * * @return tags object */ getTags() { return this.getProperties(StreamInformation.KEY_TAGS); } /** * Returns the stream property associated with the key. * * @param key property key * @return stream property as string or undefined if the key is not found */ getStringProperty(key) { if (this.#allProperties !== undefined) { return this.#allProperties[key]; } else { return undefined; } } /** * Returns the stream property associated with the key. * * @param key property key * @return stream property as number or undefined if the key is not found */ getNumberProperty(key) { if (this.#allProperties !== undefined) { return this.#allProperties[key]; } else { return undefined; } } /** * Returns the stream properties associated with the key. * * @param key properties key * @return stream properties as an object or undefined if the key is not found */ getProperties(key) { if (this.#allProperties !== undefined) { return this.#allProperties[key]; } else { return undefined; } } /** * Returns all properties found. * * @returns an object in which properties can be accessed by property names */ getAllProperties() { return this.#allProperties; } } /** * Chapter class. */ export class Chapter { static KEY_ID = "id"; static KEY_TIME_BASE = "time_base"; static KEY_START = "start"; static KEY_START_TIME = "start_time"; static KEY_END = "end"; static KEY_END_TIME = "end_time"; static KEY_TAGS = "tags"; #allProperties; constructor(properties) { this.#allProperties = properties; } /** * Returns id. * * @return id */ getId() { return this.getNumberProperty(Chapter.KEY_ID); } /** * Returns time base. * * @return time base */ getTimeBase() { return this.getStringProperty(Chapter.KEY_TIME_BASE); } /** * Returns start. * * @return start */ getStart() { return this.getNumberProperty(Chapter.KEY_START); } /** * Returns start time. * * @return start time */ getStartTime() { return this.getStringProperty(Chapter.KEY_START_TIME); } /** * Returns end. * * @return end */ getEnd() { return this.getNumberProperty(Chapter.KEY_END); } /** * Returns end time. * * @return end time */ getEndTime() { return this.getStringProperty(Chapter.KEY_END_TIME); } /** * Returns all tags. * * @return tags object */ getTags() { return this.getProperties(StreamInformation.KEY_TAGS); } /** * Returns the chapter property associated with the key. * * @param key property key * @return chapter property as string or undefined if the key is not found */ getStringProperty(key) { if (this.#allProperties !== undefined) { return this.#allProperties[key]; } else { return undefined; } } /** * Returns the chapter property associated with the key. * * @param key property key * @return chapter property as number or undefined if the key is not found */ getNumberProperty(key) { if (this.#allProperties !== undefined) { return this.#allProperties[key]; } else { return undefined; } } /** * Returns the chapter properties associated with the key. * * @param key properties key * @return chapter properties as an object or undefined if the key is not found */ getProperties(key) { if (this.#allProperties !== undefined) { return this.#allProperties[key]; } else { return undefined; } } /** * Returns all properties found. * * @returns an object in which properties can be accessed by property names */ getAllProperties() { return this.#allProperties; } }