replace execute callback with session specific complete callbacks, fixes #197

This commit is contained in:
Taner Sener 2021-12-25 13:47:37 +00:00
parent 9b34c7215f
commit 8034629c43
19 changed files with 516 additions and 164 deletions

View File

@ -114,7 +114,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
// EVENTS
public static final String EVENT_LOG_CALLBACK_EVENT = "FFmpegKitLogCallbackEvent";
public static final String EVENT_STATISTICS_CALLBACK_EVENT = "FFmpegKitStatisticsCallbackEvent";
public static final String EVENT_EXECUTE_CALLBACK_EVENT = "FFmpegKitExecuteCallbackEvent";
public static final String EVENT_COMPLETE_CALLBACK_EVENT = "FFmpegKitCompleteCallbackEvent";
// REQUEST CODES
public static final int READABLE_REQUEST_CODE = 10000;
@ -165,7 +165,9 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
}
protected void registerGlobalCallbacks() {
FFmpegKitConfig.enableExecuteCallback(this::emitSession);
FFmpegKitConfig.enableFFmpegSessionCompleteCallback(this::emitSession);
FFmpegKitConfig.enableFFprobeSessionCompleteCallback(this::emitSession);
FFmpegKitConfig.enableMediaInformationSessionCompleteCallback(this::emitSession);
FFmpegKitConfig.enableLogCallback(log -> {
if (logsEnabled.get()) {
@ -622,6 +624,9 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
case "getFFprobeSessions":
getFFprobeSessions(result);
break;
case "getMediaInformationSessions":
getMediaInformationSessions(result);
break;
case "getPackageName":
getPackageName(result);
break;
@ -827,7 +832,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFmpegSession) {
if (session.isFFmpeg()) {
final int timeout;
if (isValidPositiveNumber(waitTimeout)) {
timeout = waitTimeout;
@ -847,7 +852,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFmpegSession) {
if (session.isFFmpeg()) {
final List<Statistics> statistics = ((FFmpegSession) session).getStatistics();
resultHandler.successAsync(result, toStatisticsMapList(statistics));
} else {
@ -1020,7 +1025,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFmpegSession) {
if (session.isFFmpeg()) {
final FFmpegSessionExecuteTask ffmpegSessionExecuteTask = new FFmpegSessionExecuteTask((FFmpegSession) session, resultHandler, result);
asyncExecutorService.submit(ffmpegSessionExecuteTask);
} else {
@ -1034,7 +1039,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFprobeSession) {
if (session.isFFprobe()) {
final FFprobeSessionExecuteTask ffprobeSessionExecuteTask = new FFprobeSessionExecuteTask((FFprobeSession) session, resultHandler, result);
asyncExecutorService.submit(ffprobeSessionExecuteTask);
} else {
@ -1048,7 +1053,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof MediaInformationSession) {
if (session.isMediaInformation()) {
final int timeout;
if (isValidPositiveNumber(waitTimeout)) {
timeout = waitTimeout;
@ -1068,7 +1073,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFmpegSession) {
if (session.isFFmpeg()) {
FFmpegKitConfig.asyncFFmpegExecute((FFmpegSession) session);
resultHandler.successAsync(result, null);
} else {
@ -1082,7 +1087,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof FFprobeSession) {
if (session.isFFprobe()) {
FFmpegKitConfig.asyncFFprobeExecute((FFprobeSession) session);
resultHandler.successAsync(result, null);
} else {
@ -1096,7 +1101,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
if (session == null) {
resultHandler.errorAsync(result, "SESSION_NOT_FOUND", "Session not found.");
} else {
if (session instanceof MediaInformationSession) {
if (session.isMediaInformation()) {
final int timeout;
if (isValidPositiveNumber(waitTimeout)) {
timeout = waitTimeout;
@ -1282,7 +1287,11 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
// FFprobeKit
protected void getFFprobeSessions(@NonNull final Result result) {
resultHandler.successAsync(result, toSessionMapList(FFprobeKit.listSessions()));
resultHandler.successAsync(result, toSessionMapList(FFprobeKit.listFFprobeSessions()));
}
protected void getMediaInformationSessions(@NonNull final Result result) {
resultHandler.successAsync(result, toSessionMapList(FFprobeKit.listMediaInformationSessions()));
}
// Packages
@ -1328,7 +1337,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
sessionMap.put(KEY_SESSION_COMMAND, session.getCommand());
if (session.isFFprobe()) {
if (session instanceof MediaInformationSession) {
if (session.isMediaInformation()) {
final MediaInformationSession mediaInformationSession = (MediaInformationSession) session;
final MediaInformation mediaInformation = mediaInformationSession.getMediaInformation();
if (mediaInformation != null) {
@ -1529,7 +1538,7 @@ public class FFmpegKitFlutterPlugin implements FlutterPlugin, ActivityAware, Met
protected void emitSession(final Session session) {
final HashMap<String, Object> sessionMap = new HashMap<>();
sessionMap.put(EVENT_EXECUTE_CALLBACK_EVENT, toMap(session));
sessionMap.put(EVENT_COMPLETE_CALLBACK_EVENT, toMap(session));
resultHandler.successAsync(eventSink, sessionMap);
}

View File

@ -57,7 +57,7 @@ static int const SESSION_TYPE_MEDIA_INFORMATION = 3;
// EVENTS
static NSString *const EVENT_LOG_CALLBACK_EVENT = @"FFmpegKitLogCallbackEvent";
static NSString *const EVENT_STATISTICS_CALLBACK_EVENT = @"FFmpegKitStatisticsCallbackEvent";
static NSString *const EVENT_EXECUTE_CALLBACK_EVENT = @"FFmpegKitExecuteCallbackEvent";
static NSString *const EVENT_COMPLETE_CALLBACK_EVENT = @"FFmpegKitCompleteCallbackEvent";
// ARGUMENT NAMES
static NSString *const ARGUMENT_SESSION_ID = @"sessionId";
@ -110,9 +110,19 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
}
- (void)registerGlobalCallbacks {
[FFmpegKitConfig enableExecuteCallback:^(id<Session> session){
[FFmpegKitConfig enableFFmpegSessionCompleteCallback:^(FFmpegSession* session){
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toSessionDictionary:session];
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_EXECUTE_CALLBACK_EVENT withDictionary:dictionary]);
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_COMPLETE_CALLBACK_EVENT withDictionary:dictionary]);
}];
[FFmpegKitConfig enableFFprobeSessionCompleteCallback:^(FFprobeSession* session){
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toSessionDictionary:session];
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_COMPLETE_CALLBACK_EVENT withDictionary:dictionary]);
}];
[FFmpegKitConfig enableMediaInformationSessionCompleteCallback:^(MediaInformationSession* session){
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toSessionDictionary:session];
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_COMPLETE_CALLBACK_EVENT withDictionary:dictionary]);
}];
[FFmpegKitConfig enableLogCallback: ^(Log* log){
@ -419,6 +429,8 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
[self getFFmpegSessions:result];
} else if ([@"getFFprobeSessions" isEqualToString:call.method]) {
[self getFFprobeSessions:result];
} else if ([@"getMediaInformationSessions" isEqualToString:call.method]) {
[self getMediaInformationSessions:result];
} else if ([@"getPackageName" isEqualToString:call.method]) {
[self getPackageName:result];
} else if ([@"getExternalLibraries" isEqualToString:call.method]) {
@ -545,7 +557,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
// FFmpegSession
- (void)ffmpegSession:(NSArray*)arguments result:(FlutterResult)result {
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withExecuteCallback:nil withLogCallback:nil withStatisticsCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withCompleteCallback:nil withLogCallback:nil withStatisticsCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
result([FFmpegKitFlutterPlugin toSessionDictionary:session]);
}
@ -554,7 +566,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[FFmpegSession class]]) {
if ([session isFFmpeg]) {
int timeout;
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
timeout = [waitTimeout intValue];
@ -574,7 +586,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[FFmpegSession class]]) {
if ([session isFFmpeg]) {
NSArray* statistics = [(FFmpegSession*)session getStatistics];
result([FFmpegKitFlutterPlugin toStatisticsArray:statistics]);
} else {
@ -586,14 +598,14 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
// FFprobeSession
- (void)ffprobeSession:(NSArray*)arguments result:(FlutterResult)result {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withExecuteCallback:nil withLogCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withCompleteCallback:nil withLogCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
result([FFmpegKitFlutterPlugin toSessionDictionary:session]);
}
// MediaInformationSession
- (void)mediaInformationSession:(NSArray*)arguments result:(FlutterResult)result {
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:nil withLogCallback:nil];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withCompleteCallback:nil withLogCallback:nil];
result([FFmpegKitFlutterPlugin toSessionDictionary:session]);
}
@ -733,7 +745,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[FFmpegSession class]]) {
if ([session isFFmpeg]) {
dispatch_async(asyncDispatchQueue, ^{
[FFmpegKitConfig ffmpegExecute:(FFmpegSession*)session];
result(nil);
@ -749,7 +761,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[FFprobeSession class]]) {
if ([session isFFprobe]) {
dispatch_async(asyncDispatchQueue, ^{
[FFmpegKitConfig ffprobeExecute:(FFprobeSession*)session];
result(nil);
@ -765,7 +777,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[MediaInformationSession class]]) {
if ([session isMediaInformation]) {
int timeout;
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
timeout = [waitTimeout intValue];
@ -787,7 +799,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[FFmpegSession class]]) {
if ([session isFFmpeg]) {
[FFmpegKitConfig asyncFFmpegExecute:(FFmpegSession*)session];
result(nil);
} else {
@ -801,7 +813,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[FFprobeSession class]]) {
if ([session isFFprobe]) {
[FFmpegKitConfig asyncFFprobeExecute:(FFprobeSession*)session];
result(nil);
} else {
@ -815,7 +827,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
if (session == nil) {
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
} else {
if ([session isMemberOfClass:[MediaInformationSession class]]) {
if ([session isMediaInformation]) {
int timeout;
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
timeout = [waitTimeout intValue];
@ -1007,7 +1019,11 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
// FFprobeKit
- (void)getFFprobeSessions:(FlutterResult)result {
result([FFmpegKitFlutterPlugin toSessionArray:[FFprobeKit listSessions]]);
result([FFmpegKitFlutterPlugin toSessionArray:[FFprobeKit listFFprobeSessions]]);
}
- (void)getMediaInformationSessions:(FlutterResult)result {
result([FFmpegKitFlutterPlugin toSessionArray:[FFprobeKit listMediaInformationSessions]]);
}
// Packages
@ -1046,7 +1062,7 @@ extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
dictionary[KEY_SESSION_COMMAND] = [session getCommand];
if ([session isFFprobe]) {
if ([(AbstractSession*)session isMemberOfClass:[MediaInformationSession class]]) {
if ([session isMediaInformation]) {
MediaInformationSession *mediaInformationSession = (MediaInformationSession*)session;
dictionary[KEY_SESSION_MEDIA_INFORMATION] = [FFmpegKitFlutterPlugin toMediaInformationDictionary:[mediaInformationSession getMediaInformation]];
dictionary[KEY_SESSION_TYPE] = [NSNumber numberWithInt:SESSION_TYPE_MEDIA_INFORMATION];

View File

@ -20,7 +20,6 @@
import 'package:ffmpeg_kit_flutter_platform_interface/ffmpeg_kit_flutter_platform_interface.dart';
import 'package:flutter/services.dart';
import 'execute_callback.dart';
import 'ffmpeg_kit_config.dart';
import 'ffmpeg_session.dart';
import 'ffprobe_session.dart';
@ -35,7 +34,7 @@ import 'session_state.dart';
import 'src/ffmpeg_kit_factory.dart';
/// Abstract session implementation which includes common features shared by
/// "FFmpeg" and "FFprobe" sessions.
/// "FFmpeg", "FFprobe" and "MediaInformation" sessions.
class AbstractSession extends Session {
static FFmpegKitPlatform _platform = FFmpegKitPlatform.instance;
@ -221,11 +220,7 @@ class AbstractSession extends Session {
return session;
}
/// Returns the session specific execute callback function.
ExecuteCallback? getExecuteCallback() =>
FFmpegKitFactory.getExecuteCallback(this.getSessionId());
/// Returns the session specific log callback function.
/// Returns the session specific log callback.
LogCallback? getLogCallback() =>
FFmpegKitFactory.getLogCallback(this.getSessionId());
@ -429,6 +424,9 @@ class AbstractSession extends Session {
/// Returns whether it is an "FFprobe" session or not.
bool isFFprobe() => false;
/// Returns whether it is an "MediaInformation" session or not.
bool isMediaInformation() => false;
/// Cancels running the session.
void cancel() {}
}

View File

@ -20,9 +20,9 @@
import 'package:ffmpeg_kit_flutter_platform_interface/ffmpeg_kit_flutter_platform_interface.dart';
import 'package:flutter/services.dart';
import 'execute_callback.dart';
import 'ffmpeg_kit_config.dart';
import 'ffmpeg_session.dart';
import 'ffmpeg_session_complete_callback.dart';
import 'log_callback.dart';
import 'src/ffmpeg_kit_factory.dart';
import 'statistics_callback.dart';
@ -35,23 +35,20 @@ class FFmpegKit {
/// to split command into arguments. You can use single or double quote
/// characters to specify arguments inside your command.
static Future<FFmpegSession> execute(String command,
[ExecuteCallback? executeCallback = null,
[FFmpegSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
StatisticsCallback? statisticsCallback = null]) async =>
FFmpegKit.executeWithArguments(
FFmpegKitConfig.parseArguments(command),
executeCallback,
logCallback,
statisticsCallback);
FFmpegKit.executeWithArguments(FFmpegKitConfig.parseArguments(command),
completeCallback, logCallback, statisticsCallback);
/// Synchronously executes FFmpeg with arguments provided.
static Future<FFmpegSession> executeWithArguments(
List<String> commandArguments,
[ExecuteCallback? executeCallback = null,
[FFmpegSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
StatisticsCallback? statisticsCallback = null]) async {
final session = await FFmpegSession.create(commandArguments,
executeCallback, logCallback, statisticsCallback, null);
completeCallback, logCallback, statisticsCallback, null);
await FFmpegKitConfig.ffmpegExecute(session);
@ -62,28 +59,28 @@ class FFmpegKit {
/// 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
/// [ExecuteCallback] if you want to be notified about the result.
/// [FFmpegSessionCompleteCallback] if you want to be notified about the result.
static Future<FFmpegSession> executeAsync(String command,
[ExecuteCallback? executeCallback = null,
[FFmpegSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
StatisticsCallback? statisticsCallback = null]) async =>
FFmpegKit.executeWithArgumentsAsync(
FFmpegKitConfig.parseArguments(command),
executeCallback,
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
/// [ExecuteCallback] if you want to be notified about the result.
/// [FFmpegSessionCompleteCallback] if you want to be notified about the result.
static Future<FFmpegSession> executeWithArgumentsAsync(
List<String> commandArguments,
[ExecuteCallback? executeCallback = null,
[FFmpegSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
StatisticsCallback? statisticsCallback = null]) async {
final session = await FFmpegSession.create(commandArguments,
executeCallback, logCallback, statisticsCallback, null);
completeCallback, logCallback, statisticsCallback, null);
await FFmpegKitConfig.asyncFFmpegExecute(session);

View File

@ -20,13 +20,15 @@
import 'package:ffmpeg_kit_flutter_platform_interface/ffmpeg_kit_flutter_platform_interface.dart';
import 'package:flutter/services.dart';
import 'execute_callback.dart';
import 'ffmpeg_session.dart';
import 'ffmpeg_session_complete_callback.dart';
import 'ffprobe_session.dart';
import 'ffprobe_session_complete_callback.dart';
import 'level.dart';
import 'log_callback.dart';
import 'log_redirection_strategy.dart';
import 'media_information_session.dart';
import 'media_information_session_complete_callback.dart';
import 'session.dart';
import 'session_state.dart';
import 'signal.dart';
@ -256,7 +258,7 @@ class FFmpegKitConfig {
/// 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
/// [ExecuteCallback] if you want to be notified about the result.
/// [FFmpegSessionCompleteCallback] if you want to be notified about the result.
static Future<void> asyncFFmpegExecute(FFmpegSession ffmpegSession) async {
try {
await init();
@ -271,7 +273,7 @@ class FFmpegKitConfig {
/// 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
/// [ExecuteCallback] if you want to be notified about the result.
/// [FFprobeSessionCompleteCallback] if you want to be notified about the result.
static Future<void> asyncFFprobeExecute(FFprobeSession ffprobeSession) async {
try {
await init();
@ -286,7 +288,7 @@ class FFmpegKitConfig {
/// 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
/// [ExecuteCallback] if you want to be notified about the result.
/// [MediaInformationSessionCompleteCallback] if you want to be notified about the result.
static Future<void> asyncGetMediaInformationExecute(
MediaInformationSession mediaInformationSession,
[int? waitTimeout = null]) async {
@ -300,22 +302,55 @@ class FFmpegKitConfig {
}
}
/// Sets a global callback function to redirect FFmpeg/FFprobe logs.
/// Sets a global callback to redirect FFmpeg/FFprobe logs.
static void enableLogCallback([LogCallback? logCallback = null]) {
FFmpegKitFactory.setGlobalLogCallback(logCallback);
}
/// Sets a global callback function to redirect FFmpeg statistics.
/// Sets a global callback to redirect FFmpeg statistics.
static void enableStatisticsCallback(
[StatisticsCallback? statisticsCallback = null]) {
FFmpegKitFactory.setGlobalStatisticsCallback(statisticsCallback);
}
/// Sets a global callback function to receive execution results.
static void enableExecuteCallback([ExecuteCallback? executeCallback = null]) {
FFmpegKitFactory.setGlobalExecuteCallback(executeCallback);
/// Sets a global FFmpegSessionCompleteCallback to receive execution results
/// for FFmpeg sessions.
static void enableFFmpegSessionCompleteCallback(
[FFmpegSessionCompleteCallback? ffmpegSessionCompleteCallback = null]) {
FFmpegKitFactory.setGlobalFFmpegSessionCompleteCallback(
ffmpegSessionCompleteCallback);
}
/// Returns the global FFmpegSessionCompleteCallback set.
static FFmpegSessionCompleteCallback? getFFmpegSessionCompleteCallback() =>
FFmpegKitFactory.getGlobalFFmpegSessionCompleteCallback();
/// Sets a global FFprobeSessionCompleteCallback to receive execution results
/// for FFprobe sessions.
static void enableFFprobeSessionCompleteCallback(
[FFprobeSessionCompleteCallback? ffprobeSessionCompleteCallback = null]) {
FFmpegKitFactory.setGlobalFFprobeSessionCompleteCallback(
ffprobeSessionCompleteCallback);
}
/// Returns the global FFprobeSessionCompleteCallback set.
static FFprobeSessionCompleteCallback? getFFprobeSessionCompleteCallback() =>
FFmpegKitFactory.getGlobalFFprobeSessionCompleteCallback();
/// Sets a global MediaInformationSessionCompleteCallback to receive
/// execution results for MediaInformation sessions.
static void enableMediaInformationSessionCompleteCallback(
[MediaInformationSessionCompleteCallback?
mediaInformationSessionCompleteCallback = null]) {
FFmpegKitFactory.setGlobalMediaInformationSessionCompleteCallback(
mediaInformationSessionCompleteCallback);
}
/// Returns the global MediaInformationSessionCompleteCallback set.
static MediaInformationSessionCompleteCallback?
getMediaInformationSessionCompleteCallback() =>
FFmpegKitFactory.getGlobalMediaInformationSessionCompleteCallback();
/// Returns the current log level.
static int getLogLevel() => _activeLogLevel;
@ -424,6 +459,72 @@ class FFmpegKitConfig {
}
}
/// Returns all FFmpeg sessions in the session history.
static Future<List<FFmpegSession>> getFFmpegSessions() async {
try {
await FFmpegKitConfig.init();
return _platform.ffmpegKitListSessions().then((sessions) {
if (sessions == null) {
return List.empty();
} else {
return sessions
.map((dynamic sessionObject) => FFmpegKitFactory.mapToSession(
sessionObject as Map<dynamic, dynamic>))
.map((session) => session as FFmpegSession)
.toList();
}
});
} on PlatformException catch (e, stack) {
print("Plugin getFFmpegSessions error: ${e.message}");
return Future.error("getFFmpegSessions failed.", stack);
}
}
/// Returns all FFprobe sessions in the session history.
static Future<List<FFprobeSession>> getFFprobeSessions() async {
try {
await FFmpegKitConfig.init();
return _platform.ffprobeKitListFFprobeSessions().then((sessions) {
if (sessions == null) {
return List.empty();
} else {
return sessions
.map((dynamic sessionObject) => FFmpegKitFactory.mapToSession(
sessionObject as Map<dynamic, dynamic>))
.map((session) => session as FFprobeSession)
.toList();
}
});
} on PlatformException catch (e, stack) {
print("Plugin getFFprobeSessions error: ${e.message}");
return Future.error("getFFprobeSessions failed.", stack);
}
}
/// Returns all MediaInformation sessions in the session history.
static Future<List<MediaInformationSession>>
getMediaInformationSessions() async {
try {
await FFmpegKitConfig.init();
return _platform
.ffprobeKitListMediaInformationSessions()
.then((sessions) {
if (sessions == null) {
return List.empty();
} else {
return sessions
.map((dynamic sessionObject) => FFmpegKitFactory.mapToSession(
sessionObject as Map<dynamic, dynamic>))
.map((session) => session as MediaInformationSession)
.toList();
}
});
} on PlatformException catch (e, stack) {
print("Plugin getMediaInformationSessions error: ${e.message}");
return Future.error("getMediaInformationSessions failed.", stack);
}
}
/// Returns sessions that have [sessionState].
static Future<List<Session>> getSessionsByState(
SessionState sessionState) async {

View File

@ -21,8 +21,8 @@ import 'package:ffmpeg_kit_flutter_platform_interface/ffmpeg_kit_flutter_platfor
import 'package:flutter/services.dart';
import 'abstract_session.dart';
import 'execute_callback.dart';
import 'ffmpeg_kit_config.dart';
import 'ffmpeg_session_complete_callback.dart';
import 'log_callback.dart';
import 'log_redirection_strategy.dart';
import 'src/ffmpeg_kit_factory.dart';
@ -33,7 +33,7 @@ import 'statistics_callback.dart';
class FFmpegSession extends AbstractSession {
/// Creates a new FFmpeg session with [argumentsArray].
static Future<FFmpegSession> create(List<String> argumentsArray,
[ExecuteCallback? executeCallback = null,
[FFmpegSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
StatisticsCallback? statisticsCallback = null,
LogRedirectionStrategy? logRedirectionStrategy = null]) async {
@ -41,7 +41,8 @@ class FFmpegSession extends AbstractSession {
argumentsArray, logRedirectionStrategy);
final sessionId = session.getSessionId();
FFmpegKitFactory.setExecuteCallback(sessionId, executeCallback);
FFmpegKitFactory.setFFmpegSessionCompleteCallback(
sessionId, completeCallback);
FFmpegKitFactory.setLogCallback(sessionId, logCallback);
FFmpegKitFactory.setStatisticsCallback(sessionId, statisticsCallback);
@ -53,10 +54,14 @@ class FFmpegSession extends AbstractSession {
static FFmpegSession fromMap(Map<dynamic, dynamic> sessionMap) =>
AbstractSession.createFFmpegSessionFromMap(sessionMap);
/// Returns the session specific statistics callback function.
/// Returns the session specific statistics callback.
StatisticsCallback? getStatisticsCallback() =>
FFmpegKitFactory.getStatisticsCallback(this.getSessionId());
/// Returns the session specific complete callback.
FFmpegSessionCompleteCallback? getCompleteCallback() =>
FFmpegKitFactory.getFFmpegSessionCompleteCallback(this.getSessionId());
/// Returns all statistics entries generated for this session. If there are
/// asynchronous statistics that are not delivered yet, this method waits for
/// them until [waitTimeout].
@ -120,4 +125,6 @@ class FFmpegSession extends AbstractSession {
bool isFFmpeg() => true;
bool isFFprobe() => false;
bool isMediaInformation() => false;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2021 Taner Sener
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -17,13 +17,13 @@
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
import 'session.dart';
import 'ffmpeg_session.dart';
/// Callback function invoked when a session ends running.
/// Session has either SessionState.completed or SessionState.failed state when
/// the callback is invoked.
/// Callback function that is invoked when an asynchronous FFmpeg session has
/// ended. Session has either SessionState.completed or SessionState.failed
/// state when the callback is invoked.
/// If it has SessionState.completed state, "ReturnCode" should be checked to
/// see the execution result.
/// If "getState" returns SessionState.failed then "getFailStackTrace" should
/// be used to get the failure reason.
typedef ExecuteCallback = void Function(Session session);
typedef FFmpegSessionCompleteCallback = void Function(FFmpegSession session);

View File

@ -20,11 +20,12 @@
import 'package:ffmpeg_kit_flutter_platform_interface/ffmpeg_kit_flutter_platform_interface.dart';
import 'package:flutter/services.dart';
import 'execute_callback.dart';
import 'ffmpeg_kit_config.dart';
import 'ffprobe_session.dart';
import 'ffprobe_session_complete_callback.dart';
import 'log_callback.dart';
import 'media_information_session.dart';
import 'media_information_session_complete_callback.dart';
import 'src/ffmpeg_kit_factory.dart';
/// Main class to run "FFprobe" commands.
@ -35,20 +36,18 @@ class FFprobeKit {
/// to split command into arguments. You can use single or double quote
/// characters to specify arguments inside your command.
static Future<FFprobeSession> execute(String command,
[ExecuteCallback? executeCallback = null,
[FFprobeSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null]) async =>
FFprobeKit.executeWithArguments(
FFmpegKitConfig.parseArguments(command),
executeCallback,
logCallback);
FFprobeKit.executeWithArguments(FFmpegKitConfig.parseArguments(command),
completeCallback, logCallback);
/// Synchronously executes FFprobe with arguments provided.
static Future<FFprobeSession> executeWithArguments(
List<String> commandArguments,
[ExecuteCallback? executeCallback = null,
[FFprobeSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null]) async {
final session = await FFprobeSession.create(
commandArguments, executeCallback, logCallback, null);
commandArguments, completeCallback, logCallback, null);
await FFmpegKitConfig.ffprobeExecute(session);
@ -59,25 +58,25 @@ class FFprobeKit {
/// 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
/// [ExecuteCallback] if you want to be notified about the result.
/// [FFprobeSessionCompleteCallback] if you want to be notified about the result.
static Future<FFprobeSession> executeAsync(String command,
[ExecuteCallback? executeCallback = null,
[FFprobeSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null]) async =>
FFprobeKit.executeWithArgumentsAsync(
FFmpegKitConfig.parseArguments(command),
executeCallback,
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
/// [ExecuteCallback] if you want to be notified about the result.
/// [FFprobeSessionCompleteCallback] if you want to be notified about the result.
static Future<FFprobeSession> executeWithArgumentsAsync(
List<String> commandArguments,
[ExecuteCallback? executeCallback = null,
[FFprobeSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null]) async {
final session = await FFprobeSession.create(
commandArguments, executeCallback, logCallback, null);
commandArguments, completeCallback, logCallback, null);
await FFmpegKitConfig.asyncFFprobeExecute(session);
@ -86,7 +85,7 @@ class FFprobeKit {
/// Extracts media information for the file specified with path.
static Future<MediaInformationSession> getMediaInformation(String path,
[ExecuteCallback? executeCallback = null,
[MediaInformationSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
int? waitTimeout = null]) async {
final commandArguments = [
@ -102,7 +101,7 @@ class FFprobeKit {
path
];
return FFprobeKit.getMediaInformationFromCommandArguments(
commandArguments, executeCallback, logCallback, waitTimeout);
commandArguments, completeCallback, logCallback, waitTimeout);
}
/// Extracts media information using the command provided. The command
@ -110,12 +109,12 @@ class FFprobeKit {
/// successfully extract media information from it.
static Future<MediaInformationSession> getMediaInformationFromCommand(
String command,
[ExecuteCallback? executeCallback = null,
[MediaInformationSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
int? waitTimeout = null]) async =>
FFprobeKit.getMediaInformationFromCommandArguments(
FFmpegKitConfig.parseArguments(command),
executeCallback,
completeCallback,
logCallback,
waitTimeout);
@ -123,13 +122,12 @@ class FFprobeKit {
/// command passed to this method must generate the output in JSON format in
/// order to successfully extract media information from it.
static Future<MediaInformationSession>
getMediaInformationFromCommandArguments(
List<String> commandArguments,
[ExecuteCallback? executeCallback = null,
getMediaInformationFromCommandArguments(List<String> commandArguments,
[MediaInformationSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
int? waitTimeout = null]) async {
final session = await MediaInformationSession.create(
commandArguments, executeCallback, logCallback);
commandArguments, completeCallback, logCallback);
await FFmpegKitConfig.getMediaInformationExecute(session, waitTimeout);
@ -139,9 +137,9 @@ class FFprobeKit {
/// 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
/// [ExecuteCallback] if you want to be notified about the result.
/// [MediaInformationSessionCompleteCallback] if you want to be notified about the result.
static Future<MediaInformationSession> getMediaInformationAsync(String path,
[ExecuteCallback? executeCallback = null,
[MediaInformationSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
int? waitTimeout = null]) async {
final commandArguments = [
@ -157,22 +155,22 @@ class FFprobeKit {
path
];
return FFprobeKit.getMediaInformationFromCommandArgumentsAsync(
commandArguments, executeCallback, logCallback, waitTimeout);
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
/// [ExecuteCallback] if you want to be notified about the result.
/// [MediaInformationSessionCompleteCallback] if you want to be notified about the result.
static Future<MediaInformationSession> getMediaInformationFromCommandAsync(
String command,
[ExecuteCallback? executeCallback = null,
[MediaInformationSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
int? waitTimeout = null]) async =>
FFprobeKit.getMediaInformationFromCommandArgumentsAsync(
FFmpegKitConfig.parseArguments(command),
executeCallback,
completeCallback,
logCallback,
waitTimeout);
@ -182,16 +180,16 @@ class FFprobeKit {
/// information from it.
///
/// Note that this method returns immediately and does not wait the execution
/// to complete. You must use an [ExecuteCallback] if you want to be
/// to complete. You must use an [MediaInformationSessionCompleteCallback] if you want to be
/// notified about the result.
static Future<MediaInformationSession>
getMediaInformationFromCommandArgumentsAsync(
List<String> commandArguments,
[ExecuteCallback? executeCallback = null,
[MediaInformationSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
int? waitTimeout = null]) async {
final session = await MediaInformationSession.create(
commandArguments, executeCallback, logCallback);
commandArguments, completeCallback, logCallback);
await FFmpegKitConfig.asyncGetMediaInformationExecute(session, waitTimeout);
@ -199,10 +197,10 @@ class FFprobeKit {
}
/// Lists all FFprobe sessions in the session history.
static Future<List<FFprobeSession>> listSessions() async {
static Future<List<FFprobeSession>> listFFprobeSessions() async {
try {
await FFmpegKitConfig.init();
return _platform.ffprobeKitListSessions().then((sessions) {
return _platform.ffprobeKitListFFprobeSessions().then((sessions) {
if (sessions == null) {
return List.empty();
} else {
@ -214,8 +212,32 @@ class FFprobeKit {
}
});
} on PlatformException catch (e, stack) {
print("Plugin listSessions error: ${e.message}");
return Future.error("listSessions failed.", stack);
print("Plugin listFFprobeSessions error: ${e.message}");
return Future.error("listFFprobeSessions failed.", stack);
}
}
/// Lists all MediaInformation sessions in the session history.
static Future<List<MediaInformationSession>>
listMediaInformationSessions() async {
try {
await FFmpegKitConfig.init();
return _platform
.ffprobeKitListMediaInformationSessions()
.then((sessions) {
if (sessions == null) {
return List.empty();
} else {
return sessions
.map((dynamic sessionObject) => FFmpegKitFactory.mapToSession(
sessionObject as Map<dynamic, dynamic>))
.map((session) => session as MediaInformationSession)
.toList();
}
});
} on PlatformException catch (e, stack) {
print("Plugin listMediaInformationSessions error: ${e.message}");
return Future.error("listMediaInformationSessions failed.", stack);
}
}
}

View File

@ -18,7 +18,7 @@
*/
import 'abstract_session.dart';
import 'execute_callback.dart';
import 'ffprobe_session_complete_callback.dart';
import 'log_callback.dart';
import 'log_redirection_strategy.dart';
import 'src/ffmpeg_kit_factory.dart';
@ -27,14 +27,15 @@ import 'src/ffmpeg_kit_factory.dart';
class FFprobeSession extends AbstractSession {
/// Creates a new FFprobe session with [argumentsArray].
static Future<FFprobeSession> create(List<String> argumentsArray,
[ExecuteCallback? executeCallback = null,
[FFprobeSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
LogRedirectionStrategy? logRedirectionStrategy = null]) async {
final session = await AbstractSession.createFFprobeSession(
argumentsArray, logRedirectionStrategy);
final sessionId = session.getSessionId();
FFmpegKitFactory.setExecuteCallback(sessionId, executeCallback);
FFmpegKitFactory.setFFprobeSessionCompleteCallback(
sessionId, completeCallback);
FFmpegKitFactory.setLogCallback(sessionId, logCallback);
return session;
@ -45,7 +46,13 @@ class FFprobeSession extends AbstractSession {
static FFprobeSession fromMap(Map<dynamic, dynamic> sessionMap) =>
AbstractSession.createFFprobeSessionFromMap(sessionMap);
/// Returns the session specific complete callback.
FFprobeSessionCompleteCallback? getCompleteCallback() =>
FFmpegKitFactory.getFFprobeSessionCompleteCallback(this.getSessionId());
bool isFFmpeg() => false;
bool isFFprobe() => true;
bool isMediaInformation() => false;
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
import 'ffprobe_session.dart';
/// Callback function that is invoked when an asynchronous FFprobe session has
/// ended. Session has either SessionState.completed or SessionState.failed
/// state when the callback is invoked.
/// If it has SessionState.completed state, "ReturnCode" should be checked to
/// see the execution result.
/// If "getState" returns SessionState.failed then "getFailStackTrace" should
/// be used to get the failure reason.
typedef FFprobeSessionCompleteCallback = void Function(FFprobeSession session);

View File

@ -18,26 +18,26 @@
*/
import 'abstract_session.dart';
import 'execute_callback.dart';
import 'ffprobe_session.dart';
import 'log_callback.dart';
import 'media_information.dart';
import 'media_information_session_complete_callback.dart';
import 'src/ffmpeg_kit_factory.dart';
/// A custom FFprobe session, which produces a "MediaInformation" object
/// using the FFprobe output.
class MediaInformationSession extends FFprobeSession {
class MediaInformationSession extends AbstractSession {
MediaInformation? _mediaInformation;
/// Creates a new MediaInformation session with [argumentsArray].
static Future<MediaInformationSession> create(List<String> argumentsArray,
[ExecuteCallback? executeCallback = null,
[MediaInformationSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null]) async {
final session =
await AbstractSession.createMediaInformationSession(argumentsArray);
final sessionId = session.getSessionId();
FFmpegKitFactory.setExecuteCallback(sessionId, executeCallback);
FFmpegKitFactory.setMediaInformationSessionCompleteCallback(
sessionId, completeCallback);
FFmpegKitFactory.setLogCallback(sessionId, logCallback);
return session;
@ -55,4 +55,15 @@ class MediaInformationSession extends FFprobeSession {
void setMediaInformation(MediaInformation? mediaInformation) {
this._mediaInformation = mediaInformation;
}
/// Returns the session specific complete callback.
MediaInformationSessionCompleteCallback? getCompleteCallback() =>
FFmpegKitFactory.getMediaInformationSessionCompleteCallback(
this.getSessionId());
bool isFFmpeg() => false;
bool isFFprobe() => false;
bool isMediaInformation() => true;
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2021 Taner Sener
*
* This file is part of FFmpegKit.
*
* FFmpegKit is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FFmpegKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
import 'media_information_session.dart';
/// Callback function that is invoked when an asynchronous MediaInformation
/// session has ended. Session has either SessionState.completed or
/// SessionState.failed state when the callback is invoked.
/// If it has SessionState.completed state, "ReturnCode" should be checked to
/// see the execution result.
/// If "getState" returns SessionState.failed then "getFailStackTrace" should
/// be used to get the failure reason.
typedef MediaInformationSessionCompleteCallback = void Function(
MediaInformationSession session);

View File

@ -17,7 +17,6 @@
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
import 'execute_callback.dart';
import 'log.dart';
import 'log_callback.dart';
import 'log_redirection_strategy.dart';
@ -26,10 +25,7 @@ import 'session_state.dart';
/// Common interface for all "FFmpegKit" sessions.
abstract class Session {
/// Returns the session specific execute callback function.
ExecuteCallback? getExecuteCallback();
/// Returns the session specific log callback function.
/// Returns the session specific log callback.
LogCallback? getLogCallback();
/// Returns the session identifier.
@ -106,6 +102,9 @@ abstract class Session {
/// Returns whether it is an "FFprobe" session or not.
bool isFFprobe();
/// Returns whether it is an "MediaInformation" session or not.
bool isMediaInformation();
/// Cancels running the session.
void cancel();
}

View File

@ -17,18 +17,25 @@
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
import '../execute_callback.dart';
import '../ffmpeg_session.dart';
import '../ffmpeg_session_complete_callback.dart';
import '../ffprobe_session.dart';
import '../ffprobe_session_complete_callback.dart';
import '../log.dart';
import '../log_callback.dart';
import '../log_redirection_strategy.dart';
import '../media_information_session.dart';
import '../media_information_session_complete_callback.dart';
import '../session.dart';
import '../statistics.dart';
import '../statistics_callback.dart';
final executeCallbackMap = new Map<int, ExecuteCallback>();
final ffmpegSessionCompleteCallbackMap =
new Map<int, FFmpegSessionCompleteCallback>();
final ffprobeSessionCompleteCallbackMap =
new Map<int, FFprobeSessionCompleteCallback>();
final mediaInformationSessionCompleteCallbackMap =
new Map<int, MediaInformationSessionCompleteCallback>();
final logCallbackMap = new Map<int, LogCallback>();
final statisticsCallbackMap = new Map<int, StatisticsCallback>();
final logRedirectionStrategyMap = new Map<int, LogRedirectionStrategy>();
@ -36,7 +43,10 @@ final logRedirectionStrategyMap = new Map<int, LogRedirectionStrategy>();
class FFmpegKitFactory {
static LogCallback? _logCallback;
static StatisticsCallback? _statisticsCallback;
static ExecuteCallback? _executeCallback;
static FFmpegSessionCompleteCallback? _ffmpegSessionCompleteCallback;
static FFprobeSessionCompleteCallback? _ffprobeSessionCompleteCallback;
static MediaInformationSessionCompleteCallback?
_mediaInformationSessionCompleteCallback;
static Statistics mapToStatistics(Map<dynamic, dynamic> statisticsMap) =>
new Statistics(
@ -125,20 +135,64 @@ class FFmpegKitFactory {
_statisticsCallback = statisticsCallback;
}
static ExecuteCallback? getExecuteCallback(int? sessionId) =>
executeCallbackMap[sessionId];
static FFmpegSessionCompleteCallback? getFFmpegSessionCompleteCallback(
int? sessionId) =>
ffmpegSessionCompleteCallbackMap[sessionId];
static void setExecuteCallback(
int? sessionId, ExecuteCallback? executeCallback) {
if (sessionId != null && executeCallback != null) {
executeCallbackMap[sessionId] = executeCallback;
static void setFFmpegSessionCompleteCallback(
int? sessionId, FFmpegSessionCompleteCallback? completeCallback) {
if (sessionId != null && completeCallback != null) {
ffmpegSessionCompleteCallbackMap[sessionId] = completeCallback;
}
}
static ExecuteCallback? getGlobalExecuteCallback() => _executeCallback;
static FFmpegSessionCompleteCallback?
getGlobalFFmpegSessionCompleteCallback() =>
_ffmpegSessionCompleteCallback;
static void setGlobalExecuteCallback(ExecuteCallback? executeCallback) {
_executeCallback = executeCallback;
static void setGlobalFFmpegSessionCompleteCallback(
FFmpegSessionCompleteCallback? completeCallback) {
_ffmpegSessionCompleteCallback = completeCallback;
}
static FFprobeSessionCompleteCallback? getFFprobeSessionCompleteCallback(
int? sessionId) =>
ffprobeSessionCompleteCallbackMap[sessionId];
static void setFFprobeSessionCompleteCallback(
int? sessionId, FFprobeSessionCompleteCallback? completeCallback) {
if (sessionId != null && completeCallback != null) {
ffprobeSessionCompleteCallbackMap[sessionId] = completeCallback;
}
}
static FFprobeSessionCompleteCallback?
getGlobalFFprobeSessionCompleteCallback() =>
_ffprobeSessionCompleteCallback;
static void setGlobalFFprobeSessionCompleteCallback(
FFprobeSessionCompleteCallback? completeCallback) {
_ffprobeSessionCompleteCallback = completeCallback;
}
static MediaInformationSessionCompleteCallback?
getMediaInformationSessionCompleteCallback(int? sessionId) =>
mediaInformationSessionCompleteCallbackMap[sessionId];
static void setMediaInformationSessionCompleteCallback(int? sessionId,
MediaInformationSessionCompleteCallback? completeCallback) {
if (sessionId != null && completeCallback != null) {
mediaInformationSessionCompleteCallbackMap[sessionId] = completeCallback;
}
}
static MediaInformationSessionCompleteCallback?
getGlobalMediaInformationSessionCompleteCallback() =>
_mediaInformationSessionCompleteCallback;
static void setGlobalMediaInformationSessionCompleteCallback(
MediaInformationSessionCompleteCallback? completeCallback) {
_mediaInformationSessionCompleteCallback = completeCallback;
}
static DateTime? validDate(int? time) {

View File

@ -19,16 +19,20 @@
import 'dart:io';
import 'package:ffmpeg_kit_flutter/ffprobe_session.dart';
import 'package:ffmpeg_kit_flutter/media_information_session.dart';
import 'package:ffmpeg_kit_flutter_platform_interface/ffmpeg_kit_flutter_platform_interface.dart';
import 'package:flutter/services.dart';
import '../arch_detect.dart';
import '../execute_callback.dart';
import '../ffmpeg_kit_config.dart';
import '../ffmpeg_session.dart';
import '../ffmpeg_session_complete_callback.dart';
import '../ffprobe_session_complete_callback.dart';
import '../level.dart';
import '../log_callback.dart';
import '../log_redirection_strategy.dart';
import '../media_information_session_complete_callback.dart';
import '../packages.dart';
import '../session.dart';
import '../statistics.dart';
@ -59,8 +63,8 @@ class FFmpegKitInitializer {
eventMap['FFmpegKitLogCallbackEvent'];
final Map<dynamic, dynamic>? statisticsEvent =
eventMap['FFmpegKitStatisticsCallbackEvent'];
final Map<dynamic, dynamic>? executeEvent =
eventMap['FFmpegKitExecuteCallbackEvent'];
final Map<dynamic, dynamic>? completeEvent =
eventMap['FFmpegKitCompleteCallbackEvent'];
if (logEvent != null) {
_processLogCallbackEvent(logEvent);
@ -70,8 +74,8 @@ class FFmpegKitInitializer {
_processStatisticsCallbackEvent(statisticsEvent);
}
if (executeEvent != null) {
_processExecuteCallbackEvent(executeEvent);
if (completeEvent != null) {
_processCompleteCallbackEvent(completeEvent);
}
}
}
@ -110,7 +114,7 @@ class FFmpegKitInitializer {
// NOTIFY SESSION CALLBACK DEFINED
logCallback(log);
} on Exception catch (e, stack) {
print("Exception thrown inside session LogCallback block. $e");
print("Exception thrown inside session log callback. $e");
print(stack);
}
}
@ -123,7 +127,7 @@ class FFmpegKitInitializer {
// NOTIFY GLOBAL CALLBACK DEFINED
globalLogCallbackFunction(log);
} on Exception catch (e, stack) {
print("Exception thrown inside global LogCallback block. $e");
print("Exception thrown inside global log callback. $e");
print(stack);
}
}
@ -185,7 +189,7 @@ class FFmpegKitInitializer {
// NOTIFY SESSION CALLBACK DEFINED
statisticsCallback(statistics);
} on Exception catch (e, stack) {
print("Exception thrown inside session StatisticsCallback block. $e");
print("Exception thrown inside session statistics callback. $e");
print(stack);
}
}
@ -197,37 +201,96 @@ class FFmpegKitInitializer {
// NOTIFY GLOBAL CALLBACK DEFINED
globalStatisticsCallbackFunction(statistics);
} on Exception catch (e, stack) {
print("Exception thrown inside global StatisticsCallback block. $e");
print("Exception thrown inside global statistics callback. $e");
print(stack);
}
}
}
void _processExecuteCallbackEvent(Map<dynamic, dynamic> event) {
void _processCompleteCallbackEvent(Map<dynamic, dynamic> event) {
final int sessionId = event["sessionId"];
FFmpegKitConfig.getSession(sessionId).then((Session? session) {
final ExecuteCallback? executeCallback = session?.getExecuteCallback();
if (session != null) {
if (session.isFFmpeg()) {
final ffmpegSession = session as FFmpegSession;
final FFmpegSessionCompleteCallback? completeCallback =
ffmpegSession.getCompleteCallback();
if (executeCallback != null && session != null) {
try {
// NOTIFY SESSION CALLBACK DEFINED
executeCallback(session);
} on Exception catch (e, stack) {
print("Exception thrown inside session ExecuteCallback block. $e");
print(stack);
}
}
if (completeCallback != null) {
try {
// NOTIFY SESSION CALLBACK DEFINED
completeCallback(ffmpegSession);
} on Exception catch (e, stack) {
print("Exception thrown inside session complete callback. $e");
print(stack);
}
}
final globalExecuteCallbackFunction =
FFmpegKitFactory.getGlobalExecuteCallback();
if (globalExecuteCallbackFunction != null && session != null) {
try {
// NOTIFY GLOBAL CALLBACK DEFINED
globalExecuteCallbackFunction(session);
} on Exception catch (e, stack) {
print("Exception thrown inside global ExecuteCallback block. $e");
print(stack);
final globalFFmpegSessionCompleteCallback =
FFmpegKitFactory.getGlobalFFmpegSessionCompleteCallback();
if (globalFFmpegSessionCompleteCallback != null) {
try {
// NOTIFY GLOBAL CALLBACK DEFINED
globalFFmpegSessionCompleteCallback(ffmpegSession);
} on Exception catch (e, stack) {
print("Exception thrown inside global complete callback. $e");
print(stack);
}
}
} else if (session.isFFprobe()) {
final ffprobeSession = session as FFprobeSession;
final FFprobeSessionCompleteCallback? completeCallback =
ffprobeSession.getCompleteCallback();
if (completeCallback != null) {
try {
// NOTIFY SESSION CALLBACK DEFINED
completeCallback(ffprobeSession);
} on Exception catch (e, stack) {
print("Exception thrown inside session complete callback. $e");
print(stack);
}
}
final globalFFprobeSessionCompleteCallback =
FFmpegKitFactory.getGlobalFFprobeSessionCompleteCallback();
if (globalFFprobeSessionCompleteCallback != null) {
try {
// NOTIFY GLOBAL CALLBACK DEFINED
globalFFprobeSessionCompleteCallback(ffprobeSession);
} on Exception catch (e, stack) {
print("Exception thrown inside global complete callback. $e");
print(stack);
}
}
} else if (session.isMediaInformation()) {
final mediaInformationSession = session as MediaInformationSession;
final MediaInformationSessionCompleteCallback? completeCallback =
mediaInformationSession.getCompleteCallback();
if (completeCallback != null) {
try {
// NOTIFY SESSION CALLBACK DEFINED
completeCallback(mediaInformationSession);
} on Exception catch (e, stack) {
print("Exception thrown inside session complete callback. $e");
print(stack);
}
}
final globalMediaInformationSessionCompleteCallback = FFmpegKitFactory
.getGlobalMediaInformationSessionCompleteCallback();
if (globalMediaInformationSessionCompleteCallback != null) {
try {
// NOTIFY GLOBAL CALLBACK DEFINED
globalMediaInformationSessionCompleteCallback(
mediaInformationSession);
} on Exception catch (e, stack) {
print("Exception thrown inside global complete callback. $e");
print(stack);
}
}
}
}
});

View File

@ -19,5 +19,5 @@
import 'statistics.dart';
/// Callback function that receives statistics generated for "FFmpeg" sessions.dc
/// Callback function that receives statistics generated for "FFmpeg" sessions.
typedef StatisticsCallback = void Function(Statistics statistics);

View File

@ -57,7 +57,7 @@ static int const SESSION_TYPE_MEDIA_INFORMATION = 3;
// EVENTS
static NSString *const EVENT_LOG_CALLBACK_EVENT = @"FFmpegKitLogCallbackEvent";
static NSString *const EVENT_STATISTICS_CALLBACK_EVENT = @"FFmpegKitStatisticsCallbackEvent";
static NSString *const EVENT_EXECUTE_CALLBACK_EVENT = @"FFmpegKitExecuteCallbackEvent";
static NSString *const EVENT_EXECUTE_CALLBACK_EVENT = @"FFmpegKitCompleteCallbackEvent";
// ARGUMENT NAMES
static NSString *const ARGUMENT_SESSION_ID = @"sessionId";

View File

@ -364,9 +364,14 @@ abstract class FFmpegKitPlatform extends PlatformInterface {
// FFprobeKit
Future<List<dynamic>?> ffprobeKitListSessions() async {
Future<List<dynamic>?> ffprobeKitListFFprobeSessions() async {
throw UnimplementedError(
'ffprobeKitListSessions() has not been implemented!');
'ffprobeKitListFFprobeSessions() has not been implemented!');
}
Future<List<dynamic>?> ffprobeKitListMediaInformationSessions() async {
throw UnimplementedError(
'ffprobeKitListMediaInformationSessions() has not been implemented!');
}
// MediaInformationJsonParser

View File

@ -334,9 +334,13 @@ class MethodChannelFFmpegKit extends FFmpegKitPlatform {
// FFprobeKit
@override
Future<List<dynamic>?> ffprobeKitListSessions() async =>
Future<List<dynamic>?> ffprobeKitListFFprobeSessions() async =>
_channel.invokeMethod<List<dynamic>>('getFFprobeSessions');
@override
Future<List<dynamic>?> ffprobeKitListMediaInformationSessions() async =>
_channel.invokeMethod<List<dynamic>>('getMediaInformationSessions');
// MediaInformationJsonParser
@override