You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1238 lines
49 KiB
1238 lines
49 KiB
/*
|
|
* Copyright (c) 2018-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 "FFmpegKitFlutterPlugin.h"
|
|
|
|
#import <ffmpegkit/FFmpegKitConfig.h>
|
|
|
|
static NSString *const PLATFORM_NAME = @"ios";
|
|
|
|
static NSString *const METHOD_CHANNEL = @"flutter.arthenica.com/ffmpeg_kit";
|
|
static NSString *const EVENT_CHANNEL = @"flutter.arthenica.com/ffmpeg_kit_event";
|
|
|
|
// LOG CLASS
|
|
static NSString *const KEY_LOG_SESSION_ID = @"sessionId";
|
|
static NSString *const KEY_LOG_LEVEL = @"level";
|
|
static NSString *const KEY_LOG_MESSAGE = @"message";
|
|
|
|
// STATISTICS CLASS
|
|
static NSString *const KEY_STATISTICS_SESSION_ID = @"sessionId";
|
|
static NSString *const KEY_STATISTICS_VIDEO_FRAME_NUMBER = @"videoFrameNumber";
|
|
static NSString *const KEY_STATISTICS_VIDEO_FPS = @"videoFps";
|
|
static NSString *const KEY_STATISTICS_VIDEO_QUALITY = @"videoQuality";
|
|
static NSString *const KEY_STATISTICS_SIZE = @"size";
|
|
static NSString *const KEY_STATISTICS_TIME = @"time";
|
|
static NSString *const KEY_STATISTICS_BITRATE = @"bitrate";
|
|
static NSString *const KEY_STATISTICS_SPEED = @"speed";
|
|
|
|
// SESSION CLASS
|
|
static NSString *const KEY_SESSION_ID = @"sessionId";
|
|
static NSString *const KEY_SESSION_CREATE_TIME = @"createTime";
|
|
static NSString *const KEY_SESSION_START_TIME = @"startTime";
|
|
static NSString *const KEY_SESSION_COMMAND = @"command";
|
|
static NSString *const KEY_SESSION_TYPE = @"type";
|
|
static NSString *const KEY_SESSION_MEDIA_INFORMATION = @"mediaInformation";
|
|
|
|
// SESSION TYPE
|
|
static int const SESSION_TYPE_FFMPEG = 1;
|
|
static int const SESSION_TYPE_FFPROBE = 2;
|
|
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_COMPLETE_CALLBACK_EVENT = @"FFmpegKitCompleteCallbackEvent";
|
|
|
|
// ARGUMENT NAMES
|
|
static NSString *const ARGUMENT_SESSION_ID = @"sessionId";
|
|
static NSString *const ARGUMENT_WAIT_TIMEOUT = @"waitTimeout";
|
|
static NSString *const ARGUMENT_ARGUMENTS = @"arguments";
|
|
static NSString *const ARGUMENT_FFPROBE_JSON_OUTPUT = @"ffprobeJsonOutput";
|
|
|
|
extern int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
|
|
|
|
@implementation FFmpegKitFlutterPlugin {
|
|
FlutterEventSink _eventSink;
|
|
BOOL logsEnabled;
|
|
BOOL statisticsEnabled;
|
|
dispatch_queue_t asyncDispatchQueue;
|
|
}
|
|
|
|
- (instancetype)init {
|
|
self = [super init];
|
|
if (self) {
|
|
logsEnabled = false;
|
|
statisticsEnabled = false;
|
|
asyncDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
|
|
|
NSLog(@"FFmpegKitFlutterPlugin %p created.\n", self);
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
|
|
_eventSink = eventSink;
|
|
NSLog(@"FFmpegKitFlutterPlugin %p started listening to events on %p.\n", self, eventSink);
|
|
[self registerGlobalCallbacks];
|
|
return nil;
|
|
}
|
|
|
|
- (FlutterError *)onCancelWithArguments:(id)arguments {
|
|
_eventSink = nil;
|
|
return nil;
|
|
}
|
|
|
|
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
|
FFmpegKitFlutterPlugin* instance = [[FFmpegKitFlutterPlugin alloc] init];
|
|
|
|
FlutterMethodChannel* methodChannel = [FlutterMethodChannel methodChannelWithName:METHOD_CHANNEL binaryMessenger:[registrar messenger]];
|
|
[registrar addMethodCallDelegate:instance channel:methodChannel];
|
|
|
|
FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:EVENT_CHANNEL binaryMessenger:[registrar messenger]];
|
|
[eventChannel setStreamHandler:instance];
|
|
}
|
|
|
|
- (void)registerGlobalCallbacks {
|
|
[FFmpegKitConfig enableFFmpegSessionCompleteCallback:^(FFmpegSession* session){
|
|
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toSessionDictionary:session];
|
|
dispatch_async(dispatch_get_main_queue(), ^() {
|
|
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_COMPLETE_CALLBACK_EVENT withDictionary:dictionary]);
|
|
});
|
|
}];
|
|
|
|
[FFmpegKitConfig enableFFprobeSessionCompleteCallback:^(FFprobeSession* session){
|
|
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toSessionDictionary:session];
|
|
dispatch_async(dispatch_get_main_queue(), ^() {
|
|
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_COMPLETE_CALLBACK_EVENT withDictionary:dictionary]);
|
|
});
|
|
}];
|
|
|
|
[FFmpegKitConfig enableMediaInformationSessionCompleteCallback:^(MediaInformationSession* session){
|
|
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toSessionDictionary:session];
|
|
dispatch_async(dispatch_get_main_queue(), ^() {
|
|
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_COMPLETE_CALLBACK_EVENT withDictionary:dictionary]);
|
|
});
|
|
}];
|
|
|
|
[FFmpegKitConfig enableLogCallback: ^(Log* log){
|
|
if (self->logsEnabled) {
|
|
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toLogDictionary:log];
|
|
dispatch_async(dispatch_get_main_queue(), ^() {
|
|
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_LOG_CALLBACK_EVENT withDictionary:dictionary]);
|
|
});
|
|
}
|
|
}];
|
|
|
|
[FFmpegKitConfig enableStatisticsCallback:^(Statistics* statistics){
|
|
if (self->statisticsEnabled) {
|
|
NSDictionary *dictionary = [FFmpegKitFlutterPlugin toStatisticsDictionary:statistics];
|
|
dispatch_async(dispatch_get_main_queue(), ^() {
|
|
self->_eventSink([FFmpegKitFlutterPlugin toStringDictionary:EVENT_STATISTICS_CALLBACK_EVENT withDictionary:dictionary]);
|
|
});
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
|
NSNumber* sessionId = call.arguments[ARGUMENT_SESSION_ID];
|
|
NSNumber* waitTimeout = call.arguments[ARGUMENT_WAIT_TIMEOUT];
|
|
NSArray* arguments = call.arguments[ARGUMENT_ARGUMENTS];
|
|
NSString* ffprobeJsonOutput = call.arguments[ARGUMENT_FFPROBE_JSON_OUTPUT];
|
|
|
|
if ([@"abstractSessionGetEndTime" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetEndTime:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"abstractSessionGetDuration" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetDuration:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"abstractSessionGetAllLogs" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetAllLogs:sessionId timeout:(NSNumber*)waitTimeout result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"abstractSessionGetLogs" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetLogs:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"abstractSessionGetAllLogsAsString" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetAllLogsAsString:sessionId timeout:(NSNumber*)waitTimeout result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"abstractSessionGetState" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetState:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"abstractSessionGetReturnCode" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetReturnCode:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"abstractSessionGetFailStackTrace" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self abstractSessionGetFailStackTrace:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"thereAreAsynchronousMessagesInTransmit" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self thereAreAsynchronousMessagesInTransmit:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"getArch" isEqualToString:call.method]) {
|
|
[self getArch:result];
|
|
} else if ([@"ffmpegSession" isEqualToString:call.method]) {
|
|
if (arguments != nil) {
|
|
[self ffmpegSession:arguments result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_ARGUMENTS" message:@"Invalid arguments array." details:nil]);
|
|
}
|
|
} else if ([@"ffmpegSessionGetAllStatistics" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self ffmpegSessionGetAllStatistics:sessionId timeout:(NSNumber*)waitTimeout result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"ffmpegSessionGetStatistics" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self ffmpegSessionGetStatistics:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"ffprobeSession" isEqualToString:call.method]) {
|
|
if (arguments != nil) {
|
|
[self ffprobeSession:arguments result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_ARGUMENTS" message:@"Invalid arguments array." details:nil]);
|
|
}
|
|
} else if ([@"mediaInformationSession" isEqualToString:call.method]) {
|
|
if (arguments != nil) {
|
|
[self mediaInformationSession:arguments result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_ARGUMENTS" message:@"Invalid arguments array." details:nil]);
|
|
}
|
|
} else if ([@"getMediaInformation" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self getMediaInformation:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"mediaInformationJsonParserFrom" isEqualToString:call.method]) {
|
|
if (ffprobeJsonOutput != nil) {
|
|
[self mediaInformationJsonParserFrom:ffprobeJsonOutput result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_FFPROBE_JSON_OUTPUT" message:@"Invalid ffprobe json output." details:nil]);
|
|
}
|
|
} else if ([@"mediaInformationJsonParserFromWithError" isEqualToString:call.method]) {
|
|
if (ffprobeJsonOutput != nil) {
|
|
[self mediaInformationJsonParserFromWithError:ffprobeJsonOutput result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_FFPROBE_JSON_OUTPUT" message:@"Invalid ffprobe json output." details:nil]);
|
|
}
|
|
} else if ([@"enableRedirection" isEqualToString:call.method]) {
|
|
[self enableRedirection:result];
|
|
} else if ([@"disableRedirection" isEqualToString:call.method]) {
|
|
[self disableRedirection:result];
|
|
} else if ([@"enableLogs" isEqualToString:call.method]) {
|
|
[self enableLogs:result];
|
|
} else if ([@"disableLogs" isEqualToString:call.method]) {
|
|
[self disableLogs:result];
|
|
} else if ([@"enableStatistics" isEqualToString:call.method]) {
|
|
[self enableStatistics:result];
|
|
} else if ([@"disableStatistics" isEqualToString:call.method]) {
|
|
[self disableStatistics:result];
|
|
} else if ([@"setFontconfigConfigurationPath" isEqualToString:call.method]) {
|
|
NSString* path = call.arguments[@"path"];
|
|
if (path != nil) {
|
|
[self setFontconfigConfigurationPath:path result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_PATH" message:@"Invalid path." details:nil]);
|
|
}
|
|
} else if ([@"setFontDirectory" isEqualToString:call.method]) {
|
|
NSString* fontDirectory = call.arguments[@"fontDirectory"];
|
|
NSDictionary* fontNameMap = call.arguments[@"fontNameMap"];
|
|
if (fontDirectory != nil) {
|
|
[self setFontDirectory:fontDirectory mapping:fontNameMap result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_FONT_DIRECTORY" message:@"Invalid font directory." details:nil]);
|
|
}
|
|
} else if ([@"setFontDirectoryList" isEqualToString:call.method]) {
|
|
NSArray* fontDirectoryList = call.arguments[@"fontDirectoryList"];
|
|
NSDictionary* fontNameMap = call.arguments[@"fontNameMap"];
|
|
if (fontDirectoryList != nil) {
|
|
[self setFontDirectoryList:fontDirectoryList mapping:fontNameMap result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_FONT_DIRECTORY_LIST" message:@"Invalid font directory list." details:nil]);
|
|
}
|
|
} else if ([@"registerNewFFmpegPipe" isEqualToString:call.method]) {
|
|
[self registerNewFFmpegPipe:result];
|
|
} else if ([@"closeFFmpegPipe" isEqualToString:call.method]) {
|
|
NSString* ffmpegPipePath = call.arguments[@"ffmpegPipePath"];
|
|
if (ffmpegPipePath != nil) {
|
|
[self closeFFmpegPipe:ffmpegPipePath result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_PIPE_PATH" message:@"Invalid ffmpeg pipe path." details:nil]);
|
|
}
|
|
} else if ([@"getFFmpegVersion" isEqualToString:call.method]) {
|
|
[self getFFmpegVersion:result];
|
|
} else if ([@"isLTSBuild" isEqualToString:call.method]) {
|
|
[self isLTSBuild:result];
|
|
} else if ([@"getBuildDate" isEqualToString:call.method]) {
|
|
[self getBuildDate:result];
|
|
} else if ([@"setEnvironmentVariable" isEqualToString:call.method]) {
|
|
NSString* variableName = call.arguments[@"variableName"];
|
|
NSString* variableValue = call.arguments[@"variableValue"];
|
|
if ((variableName != nil) && (variableValue != nil)) {
|
|
[self setEnvironmentVariable:variableName value:variableValue result:result];
|
|
} else if (variableValue != nil) {
|
|
result([FlutterError errorWithCode:@"INVALID_NAME" message:@"Invalid environment variable name." details:nil]);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_VALUE" message:@"Invalid environment variable value." details:nil]);
|
|
}
|
|
} else if ([@"ignoreSignal" isEqualToString:call.method]) {
|
|
NSNumber* signalIndex = call.arguments[@"signal"];
|
|
if (signalIndex != nil) {
|
|
[self ignoreSignal:[signalIndex intValue] result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SIGNAL" message:@"Invalid signal value." details:nil]);
|
|
}
|
|
} else if ([@"ffmpegSessionExecute" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self ffmpegSessionExecute:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"ffprobeSessionExecute" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self ffprobeSessionExecute:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"mediaInformationSessionExecute" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self mediaInformationSessionExecute:sessionId timeout:waitTimeout result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"asyncFFmpegSessionExecute" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self asyncFFmpegSessionExecute:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"asyncFFprobeSessionExecute" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self asyncFFprobeSessionExecute:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"asyncMediaInformationSessionExecute" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self asyncMediaInformationSessionExecute:sessionId timeout:waitTimeout result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"getLogLevel" isEqualToString:call.method]) {
|
|
[self getLogLevel:result];
|
|
} else if ([@"setLogLevel" isEqualToString:call.method]) {
|
|
NSNumber* level = call.arguments[@"level"];
|
|
if (level != nil) {
|
|
[self setLogLevel:level result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_LEVEL" message:@"Invalid level value." details:nil]);
|
|
}
|
|
} else if ([@"getSessionHistorySize" isEqualToString:call.method]) {
|
|
[self getSessionHistorySize:result];
|
|
} else if ([@"setSessionHistorySize" isEqualToString:call.method]) {
|
|
NSNumber* sessionHistorySize = call.arguments[@"sessionHistorySize"];
|
|
if (sessionHistorySize != nil) {
|
|
[self setSessionHistorySize:sessionHistorySize result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SIZE" message:@"Invalid session history size value." details:nil]);
|
|
}
|
|
} else if ([@"getSession" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self getSession:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"getLastSession" isEqualToString:call.method]) {
|
|
[self getLastSession:result];
|
|
} else if ([@"getLastCompletedSession" isEqualToString:call.method]) {
|
|
[self getLastCompletedSession:result];
|
|
} else if ([@"getSessions" isEqualToString:call.method]) {
|
|
[self getSessions:result];
|
|
} else if ([@"clearSessions" isEqualToString:call.method]) {
|
|
[self clearSessions:result];
|
|
} else if ([@"getSessionsByState" isEqualToString:call.method]) {
|
|
NSNumber* stateIndex = call.arguments[@"state"];
|
|
if (stateIndex != nil) {
|
|
[self getSessionsByState:[stateIndex intValue] result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION_STATE" message:@"Invalid session state value." details:nil]);
|
|
}
|
|
} else if ([@"getLogRedirectionStrategy" isEqualToString:call.method]) {
|
|
[self getLogRedirectionStrategy:result];
|
|
} else if ([@"setLogRedirectionStrategy" isEqualToString:call.method]) {
|
|
NSNumber* strategyIndex = call.arguments[@"strategy"];
|
|
if (strategyIndex != nil) {
|
|
[self setLogRedirectionStrategy:[strategyIndex intValue] result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_LOG_REDIRECTION_STRATEGY" message:@"Invalid log redirection strategy value." details:nil]);
|
|
}
|
|
} else if ([@"messagesInTransmit" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self messagesInTransmit:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"getPlatform" isEqualToString:call.method]) {
|
|
[self getPlatform:result];
|
|
} else if ([@"writeToPipe" isEqualToString:call.method]) {
|
|
NSString* input = call.arguments[@"input"];
|
|
NSString* pipe = call.arguments[@"pipe"];
|
|
if ((input != nil) && (pipe != nil)) {
|
|
[self writeToPipe:input pipe:pipe result:result];
|
|
} else if (pipe != nil) {
|
|
result([FlutterError errorWithCode:@"INVALID_INPUT" message:@"Invalid input value." details:nil]);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_PIPE" message:@"Invalid pipe value." details:nil]);
|
|
}
|
|
} else if ([@"selectDocument" isEqualToString:call.method]) {
|
|
[self selectDocument:result];
|
|
} else if ([@"getSafParameter" isEqualToString:call.method]) {
|
|
[self getSafParameter:result];
|
|
} else if ([@"cancel" isEqualToString:call.method]) {
|
|
[self cancel:result];
|
|
} else if ([@"cancelSession" isEqualToString:call.method]) {
|
|
if (sessionId != nil) {
|
|
[self cancelSession:sessionId result:result];
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION" message:@"Invalid session id." details:nil]);
|
|
}
|
|
} else if ([@"getFFmpegSessions" isEqualToString:call.method]) {
|
|
[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]) {
|
|
[self getExternalLibraries:result];
|
|
} else {
|
|
|
|
result(FlutterMethodNotImplemented);
|
|
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetEndTime:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
NSDate* endTime = [session getEndTime];
|
|
if (endTime == nil) {
|
|
result(nil);
|
|
} else {
|
|
result([NSNumber numberWithLong:[endTime timeIntervalSince1970]*1000]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetDuration:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
result([NSNumber numberWithLong:[session getDuration]]);
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetAllLogs:(NSNumber*)sessionId timeout:(NSNumber*)waitTimeout result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
int timeout;
|
|
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
|
|
timeout = [waitTimeout intValue];
|
|
} else {
|
|
timeout = AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
|
|
}
|
|
NSArray* allLogs = [session getAllLogsWithTimeout:timeout];
|
|
result([FFmpegKitFlutterPlugin toLogArray:allLogs]);
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetLogs:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
NSArray* logs = [session getLogs];
|
|
result([FFmpegKitFlutterPlugin toLogArray:logs]);
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetAllLogsAsString:(NSNumber*)sessionId timeout:(NSNumber*)waitTimeout result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
int timeout;
|
|
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
|
|
timeout = [waitTimeout intValue];
|
|
} else {
|
|
timeout = AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
|
|
}
|
|
NSString* allLogsAsString = [session getAllLogsAsStringWithTimeout:timeout];
|
|
result(allLogsAsString);
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetState:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
result([FFmpegKitFlutterPlugin sessionStateToNumber:[session getState]]);
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetReturnCode:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
ReturnCode* returnCode = [session getReturnCode];
|
|
if (returnCode == nil) {
|
|
result(nil);
|
|
} else {
|
|
result([NSNumber numberWithInt:[returnCode getValue]]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)abstractSessionGetFailStackTrace:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
result([session getFailStackTrace]);
|
|
}
|
|
}
|
|
|
|
- (void)thereAreAsynchronousMessagesInTransmit:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
result([NSNumber numberWithBool:[session thereAreAsynchronousMessagesInTransmit]]);
|
|
}
|
|
}
|
|
|
|
// ArchDetect
|
|
|
|
- (void)getArch:(FlutterResult)result {
|
|
result([ArchDetect getArch]);
|
|
}
|
|
|
|
// FFmpegSession
|
|
|
|
- (void)ffmpegSession:(NSArray*)arguments result:(FlutterResult)result {
|
|
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withCompleteCallback:nil withLogCallback:nil withStatisticsCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
|
|
result([FFmpegKitFlutterPlugin toSessionDictionary:session]);
|
|
}
|
|
|
|
- (void)ffmpegSessionGetAllStatistics:(NSNumber*)sessionId timeout:(NSNumber*)waitTimeout result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isFFmpeg]) {
|
|
int timeout;
|
|
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
|
|
timeout = [waitTimeout intValue];
|
|
} else {
|
|
timeout = AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
|
|
}
|
|
NSArray* allStatistics = [(FFmpegSession*)session getAllStatisticsWithTimeout:timeout];
|
|
result([FFmpegKitFlutterPlugin toStatisticsArray:allStatistics]);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_FFMPEG_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)ffmpegSessionGetStatistics:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isFFmpeg]) {
|
|
NSArray* statistics = [(FFmpegSession*)session getStatistics];
|
|
result([FFmpegKitFlutterPlugin toStatisticsArray:statistics]);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_FFMPEG_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// FFprobeSession
|
|
|
|
- (void)ffprobeSession:(NSArray*)arguments result:(FlutterResult)result {
|
|
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 withCompleteCallback:nil withLogCallback:nil];
|
|
result([FFmpegKitFlutterPlugin toSessionDictionary:session]);
|
|
}
|
|
|
|
- (void)getMediaInformation:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isMediaInformation]) {
|
|
MediaInformationSession *mediaInformationSession = (MediaInformationSession*)session;
|
|
result([FFmpegKitFlutterPlugin toMediaInformationDictionary:[mediaInformationSession getMediaInformation]]);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_MEDIA_INFORMATION_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// MediaInformationJsonParser
|
|
|
|
- (void)mediaInformationJsonParserFrom:(NSString*)ffprobeJsonOutput result:(FlutterResult)result {
|
|
NSError *error;
|
|
MediaInformation* mediaInformation = [MediaInformationJsonParser from:ffprobeJsonOutput with:error];
|
|
if (error == nil) {
|
|
result([FFmpegKitFlutterPlugin toMediaInformationDictionary:mediaInformation]);
|
|
} else {
|
|
NSLog(@"Parsing MediaInformation failed: %@.\n", error);
|
|
result(nil);
|
|
}
|
|
}
|
|
|
|
- (void)mediaInformationJsonParserFromWithError:(NSString*)ffprobeJsonOutput result:(FlutterResult)result {
|
|
NSError *error;
|
|
MediaInformation* mediaInformation = [MediaInformationJsonParser from:ffprobeJsonOutput with:error];
|
|
if (error == nil) {
|
|
result([FFmpegKitFlutterPlugin toMediaInformationDictionary:mediaInformation]);
|
|
} else {
|
|
NSLog(@"Parsing MediaInformation failed: %@.\n", error);
|
|
result([FlutterError errorWithCode:@"PARSE_FAILED" message:@"Parsing MediaInformation failed with JSON error." details:nil]);
|
|
}
|
|
}
|
|
|
|
// FFmpegKitConfig
|
|
|
|
- (void)enableRedirection:(FlutterResult)result {
|
|
[self enableLogs];
|
|
[self enableStatistics];
|
|
[FFmpegKitConfig enableRedirection];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)disableRedirection:(FlutterResult)result {
|
|
[FFmpegKitConfig disableRedirection];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)enableLogs:(FlutterResult)result {
|
|
[self enableLogs];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)disableLogs:(FlutterResult)result {
|
|
[self disableLogs];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)enableStatistics:(FlutterResult)result {
|
|
[self enableStatistics];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)disableStatistics:(FlutterResult)result {
|
|
[self disableStatistics];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)setFontconfigConfigurationPath:(NSString*)path result:(FlutterResult)result {
|
|
[FFmpegKitConfig setFontconfigConfigurationPath:path];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)setFontDirectory:(NSString*)fontDirectoryPath mapping:(NSDictionary*)fontNameMap result:(FlutterResult)result {
|
|
[FFmpegKitConfig setFontDirectory:fontDirectoryPath with:fontNameMap];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)setFontDirectoryList:(NSArray*)fontDirectoryList mapping:(NSDictionary*)fontNameMap result:(FlutterResult)result {
|
|
[FFmpegKitConfig setFontDirectoryList:fontDirectoryList with:fontNameMap];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)registerNewFFmpegPipe:(FlutterResult)result {
|
|
result([FFmpegKitConfig registerNewFFmpegPipe]);
|
|
}
|
|
|
|
- (void)closeFFmpegPipe:(NSString*)ffmpegPipePath result:(FlutterResult)result {
|
|
[FFmpegKitConfig closeFFmpegPipe:ffmpegPipePath];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)getFFmpegVersion:(FlutterResult)result {
|
|
result([FFmpegKitConfig getFFmpegVersion]);
|
|
}
|
|
|
|
- (void)isLTSBuild:(FlutterResult)result {
|
|
result([NSNumber numberWithBool:([FFmpegKitConfig isLTSBuild] == 1)]);
|
|
}
|
|
|
|
- (void)getBuildDate:(FlutterResult)result {
|
|
result([FFmpegKitConfig getBuildDate]);
|
|
}
|
|
|
|
- (void)setEnvironmentVariable:(NSString*)variableName value:(NSString*)variableValue result:(FlutterResult)result {
|
|
[FFmpegKitConfig setEnvironmentVariable:variableName value:variableValue];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)ignoreSignal:(int)signalIndex result:(FlutterResult)result {
|
|
if ((signalIndex == 0) || (signalIndex == 1) || (signalIndex == 2) || (signalIndex == 3) || (signalIndex == 4)) {
|
|
Signal signalValue;
|
|
if (signalIndex == 0) {
|
|
signalValue = SignalInt;
|
|
} else if (signalIndex == 1) {
|
|
signalValue = SignalQuit;
|
|
} else if (signalIndex == 2) {
|
|
signalValue = SignalPipe;
|
|
} else if (signalIndex == 3) {
|
|
signalValue = SignalTerm;
|
|
} else {
|
|
signalValue = SignalXcpu;
|
|
}
|
|
[FFmpegKitConfig ignoreSignal:signalValue];
|
|
result(nil);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SIGNAL" message:@"Signal value not supported." details:nil]);
|
|
}
|
|
}
|
|
|
|
- (void)ffmpegSessionExecute:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isFFmpeg]) {
|
|
dispatch_async(asyncDispatchQueue, ^{
|
|
[FFmpegKitConfig ffmpegExecute:(FFmpegSession*)session];
|
|
result(nil);
|
|
});
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_FFMPEG_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)ffprobeSessionExecute:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isFFprobe]) {
|
|
dispatch_async(asyncDispatchQueue, ^{
|
|
[FFmpegKitConfig ffprobeExecute:(FFprobeSession*)session];
|
|
result(nil);
|
|
});
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_FFPROBE_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)mediaInformationSessionExecute:(NSNumber*)sessionId timeout:(NSNumber*)waitTimeout result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isMediaInformation]) {
|
|
int timeout;
|
|
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
|
|
timeout = [waitTimeout intValue];
|
|
} else {
|
|
timeout = AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
|
|
}
|
|
dispatch_async(asyncDispatchQueue, ^{
|
|
[FFmpegKitConfig getMediaInformationExecute:(MediaInformationSession*)session withTimeout:timeout];
|
|
result(nil);
|
|
});
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_MEDIA_INFORMATION_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)asyncFFmpegSessionExecute:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isFFmpeg]) {
|
|
[FFmpegKitConfig asyncFFmpegExecute:(FFmpegSession*)session];
|
|
result(nil);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_FFMPEG_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)asyncFFprobeSessionExecute:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isFFprobe]) {
|
|
[FFmpegKitConfig asyncFFprobeExecute:(FFprobeSession*)session];
|
|
result(nil);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_FFPROBE_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)asyncMediaInformationSessionExecute:(NSNumber*)sessionId timeout:(NSNumber*)waitTimeout result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
if ([session isMediaInformation]) {
|
|
int timeout;
|
|
if ([FFmpegKitFlutterPlugin isValidPositiveNumber:waitTimeout]) {
|
|
timeout = [waitTimeout intValue];
|
|
} else {
|
|
timeout = AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit;
|
|
}
|
|
[FFmpegKitConfig asyncGetMediaInformationExecute:(MediaInformationSession*)session withTimeout:timeout];
|
|
result(nil);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"NOT_MEDIA_INFORMATION_SESSION" message:@"A session is found but it does not have the correct type." details:nil]);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)getLogLevel:(FlutterResult)result {
|
|
result([NSNumber numberWithInt:[FFmpegKitConfig getLogLevel]]);
|
|
}
|
|
|
|
- (void)setLogLevel:(NSNumber*)level result:(FlutterResult)result {
|
|
[FFmpegKitConfig setLogLevel:[level intValue]];
|
|
result(nil);
|
|
}
|
|
|
|
- (void)getSessionHistorySize:(FlutterResult)result {
|
|
result([NSNumber numberWithInt:[FFmpegKitConfig getSessionHistorySize]]);
|
|
}
|
|
|
|
- (void)setSessionHistorySize:(NSNumber*)sessionHistorySize result:(FlutterResult)result {
|
|
[FFmpegKitConfig setSessionHistorySize:[sessionHistorySize intValue]];
|
|
result(nil);
|
|
}
|
|
|
|
- (void)getSession:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
AbstractSession* session = (AbstractSession*)[FFmpegKitConfig getSession:[sessionId longValue]];
|
|
if (session == nil) {
|
|
result([FlutterError errorWithCode:@"SESSION_NOT_FOUND" message:@"Session not found." details:nil]);
|
|
} else {
|
|
result([FFmpegKitFlutterPlugin toSessionDictionary:session]);
|
|
}
|
|
}
|
|
|
|
- (void)getLastSession:(FlutterResult)result {
|
|
result([FFmpegKitFlutterPlugin toSessionDictionary:[FFmpegKitConfig getLastSession]]);
|
|
}
|
|
|
|
- (void)getLastCompletedSession:(FlutterResult)result {
|
|
result([FFmpegKitFlutterPlugin toSessionDictionary:[FFmpegKitConfig getLastSession]]);
|
|
}
|
|
|
|
- (void)getSessions:(FlutterResult)result {
|
|
result([FFmpegKitFlutterPlugin toSessionArray:[FFmpegKitConfig getSessions]]);
|
|
}
|
|
|
|
- (void)clearSessions:(FlutterResult)result {
|
|
[FFmpegKitConfig clearSessions];
|
|
result(nil);
|
|
}
|
|
|
|
- (void)getSessionsByState:(int)stateIndex result:(FlutterResult)result {
|
|
if ((stateIndex == 0) || (stateIndex == 1) || (stateIndex == 2) || (stateIndex == 3)) {
|
|
NSUInteger sessionState;
|
|
if (stateIndex == 0) {
|
|
sessionState = SessionStateCreated;
|
|
} else if (stateIndex == 1) {
|
|
sessionState = SessionStateRunning;
|
|
} else if (stateIndex == 2) {
|
|
sessionState = SessionStateFailed;
|
|
} else {
|
|
sessionState = SessionStateCompleted;
|
|
}
|
|
result([FFmpegKitFlutterPlugin toSessionArray:[FFmpegKitConfig getSessionsByState:sessionState]]);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_SESSION_STATE" message:@"Session state value not supported." details:nil]);
|
|
}
|
|
}
|
|
|
|
- (void)getLogRedirectionStrategy:(FlutterResult)result {
|
|
result([FFmpegKitFlutterPlugin logRedirectionStrategyToNumber:[FFmpegKitConfig getLogRedirectionStrategy]]);
|
|
}
|
|
|
|
- (void)setLogRedirectionStrategy:(int)strategyIndex result:(FlutterResult)result {
|
|
if ((strategyIndex == 0) || (strategyIndex == 1) || (strategyIndex == 2) || (strategyIndex == 3) || (strategyIndex == 4)) {
|
|
NSUInteger logRedirectionStrategy;
|
|
if (strategyIndex == 0) {
|
|
logRedirectionStrategy = LogRedirectionStrategyAlwaysPrintLogs;
|
|
} else if (strategyIndex == 1) {
|
|
logRedirectionStrategy = LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined;
|
|
} else if (strategyIndex == 2) {
|
|
logRedirectionStrategy = LogRedirectionStrategyPrintLogsWhenGlobalCallbackNotDefined;
|
|
} else if (strategyIndex == 3) {
|
|
logRedirectionStrategy = LogRedirectionStrategyPrintLogsWhenSessionCallbackNotDefined;
|
|
} else {
|
|
logRedirectionStrategy = LogRedirectionStrategyNeverPrintLogs;
|
|
}
|
|
[FFmpegKitConfig setLogRedirectionStrategy:logRedirectionStrategy];
|
|
result(nil);
|
|
} else {
|
|
result([FlutterError errorWithCode:@"INVALID_LOG_REDIRECTION_STRATEGY" message:@"Log redirection strategy value not supported." details:nil]);
|
|
}
|
|
}
|
|
|
|
- (void)messagesInTransmit:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
result([NSNumber numberWithInt:[FFmpegKitConfig messagesInTransmit:[sessionId longValue]]]);
|
|
}
|
|
|
|
- (void)getPlatform:(FlutterResult)result {
|
|
result(PLATFORM_NAME);
|
|
}
|
|
|
|
- (void)writeToPipe:(NSString*)inputPath pipe:(NSString*)namedPipePath result:(FlutterResult)result {
|
|
dispatch_async(asyncDispatchQueue, ^{
|
|
|
|
NSLog(@"Starting copy %@ to pipe %@ operation.\n", inputPath, namedPipePath);
|
|
|
|
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath: inputPath];
|
|
if (fileHandle == nil) {
|
|
NSLog(@"Failed to open file %@.\n", inputPath);
|
|
result([FlutterError errorWithCode:@"COPY_FAILED" message:[NSString stringWithFormat:@"Failed to open file %@.", inputPath] details:nil]);
|
|
return;
|
|
}
|
|
|
|
NSFileHandle *pipeHandle = [NSFileHandle fileHandleForWritingAtPath: namedPipePath];
|
|
if (pipeHandle == nil) {
|
|
NSLog(@"Failed to open pipe %@.\n", namedPipePath);
|
|
result([FlutterError errorWithCode:@"COPY_FAILED" message:[NSString stringWithFormat:@"Failed to open pipe %@.", namedPipePath] details:nil]);
|
|
[fileHandle closeFile];
|
|
return;
|
|
}
|
|
|
|
int BUFFER_SIZE = 4096;
|
|
unsigned long readBytes = 0;
|
|
unsigned long totalBytes = 0;
|
|
double startTime = CACurrentMediaTime();
|
|
|
|
@try {
|
|
[fileHandle seekToFileOffset: 0];
|
|
|
|
do {
|
|
NSData *data = [fileHandle readDataOfLength:BUFFER_SIZE];
|
|
readBytes = [data length];
|
|
if (readBytes > 0) {
|
|
totalBytes += readBytes;
|
|
[pipeHandle writeData:data];
|
|
}
|
|
} while (readBytes > 0);
|
|
|
|
double endTime = CACurrentMediaTime();
|
|
|
|
NSLog(@"Copying %@ to pipe %@ operation completed successfully. %lu bytes copied in %f seconds.\n", inputPath, namedPipePath, totalBytes, (endTime - startTime)/1000);
|
|
|
|
result(0);
|
|
|
|
} @catch (NSException *e) {
|
|
NSLog(@"Copy failed %@.\n", [e reason]);
|
|
result([FlutterError errorWithCode:@"COPY_FAILED" message:[NSString stringWithFormat:@"Copy %@ to %@ failed with error %@.", inputPath, namedPipePath, [e reason]] details:nil]);
|
|
} @finally {
|
|
[fileHandle closeFile];
|
|
[pipeHandle closeFile];
|
|
}
|
|
});
|
|
}
|
|
|
|
- (void)selectDocument:(FlutterResult)result {
|
|
result([FlutterError errorWithCode:@"NOT_SUPPORTED" message:@"Not supported on iOS platform." details:nil]);
|
|
}
|
|
|
|
- (void)getSafParameter:(FlutterResult)result {
|
|
result([FlutterError errorWithCode:@"NOT_SUPPORTED" message:@"Not supported on iOS platform." details:nil]);
|
|
}
|
|
|
|
// FFmpegKit
|
|
|
|
- (void)cancel:(FlutterResult)result {
|
|
[FFmpegKit cancel];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)cancelSession:(NSNumber*)sessionId result:(FlutterResult)result {
|
|
[FFmpegKit cancel:[sessionId longValue]];
|
|
|
|
result(nil);
|
|
}
|
|
|
|
- (void)getFFmpegSessions:(FlutterResult)result {
|
|
result([FFmpegKitFlutterPlugin toSessionArray:[FFmpegKit listSessions]]);
|
|
}
|
|
|
|
// FFprobeKit
|
|
|
|
- (void)getFFprobeSessions:(FlutterResult)result {
|
|
result([FFmpegKitFlutterPlugin toSessionArray:[FFprobeKit listFFprobeSessions]]);
|
|
}
|
|
|
|
- (void)getMediaInformationSessions:(FlutterResult)result {
|
|
result([FFmpegKitFlutterPlugin toSessionArray:[FFprobeKit listMediaInformationSessions]]);
|
|
}
|
|
|
|
// Packages
|
|
|
|
- (void)getPackageName:(FlutterResult)result {
|
|
result([Packages getPackageName]);
|
|
}
|
|
|
|
- (void)getExternalLibraries:(FlutterResult)result {
|
|
result([Packages getExternalLibraries]);
|
|
}
|
|
|
|
- (void)enableLogs {
|
|
logsEnabled = true;
|
|
}
|
|
|
|
- (void)disableLogs {
|
|
logsEnabled = false;
|
|
}
|
|
|
|
- (void)enableStatistics {
|
|
statisticsEnabled = true;
|
|
}
|
|
|
|
- (void)disableStatistics {
|
|
statisticsEnabled = false;
|
|
}
|
|
|
|
+ (NSDictionary*)toSessionDictionary:(id<Session>) session {
|
|
if (session != nil) {
|
|
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
|
|
|
dictionary[KEY_SESSION_ID] = [NSNumber numberWithLong: [session getSessionId]];
|
|
dictionary[KEY_SESSION_CREATE_TIME] = [NSNumber numberWithLong:[[session getCreateTime] timeIntervalSince1970]*1000];
|
|
dictionary[KEY_SESSION_START_TIME] = [NSNumber numberWithLong:[[session getStartTime] timeIntervalSince1970]*1000];
|
|
dictionary[KEY_SESSION_COMMAND] = [session getCommand];
|
|
|
|
if ([session isFFmpeg]) {
|
|
dictionary[KEY_SESSION_TYPE] = [NSNumber numberWithInt:SESSION_TYPE_FFMPEG];
|
|
} else if ([session isFFprobe]) {
|
|
dictionary[KEY_SESSION_TYPE] = [NSNumber numberWithInt:SESSION_TYPE_FFPROBE];
|
|
} else 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];
|
|
}
|
|
|
|
return dictionary;
|
|
} else {
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
+ (NSDictionary*)toLogDictionary:(Log*)log {
|
|
if (log != nil) {
|
|
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
|
|
|
dictionary[KEY_LOG_SESSION_ID] = [NSNumber numberWithLong: [log getSessionId]];
|
|
dictionary[KEY_LOG_LEVEL] = [NSNumber numberWithInt: [log getLevel]];
|
|
dictionary[KEY_LOG_MESSAGE] = [log getMessage];
|
|
|
|
return dictionary;
|
|
} else {
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
+ (NSDictionary*)toStatisticsDictionary:(Statistics*)statistics {
|
|
if (statistics != nil) {
|
|
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
|
|
|
dictionary[KEY_STATISTICS_SESSION_ID] = [NSNumber numberWithLong: [statistics getSessionId]];
|
|
dictionary[KEY_STATISTICS_VIDEO_FRAME_NUMBER] = [NSNumber numberWithInt: [statistics getVideoFrameNumber]];
|
|
dictionary[KEY_STATISTICS_VIDEO_FPS] = [NSNumber numberWithFloat: [statistics getVideoFps]];
|
|
dictionary[KEY_STATISTICS_VIDEO_QUALITY] = [NSNumber numberWithFloat: [statistics getVideoQuality]];
|
|
dictionary[KEY_STATISTICS_SIZE] = [NSNumber numberWithLong: [statistics getSize]];
|
|
dictionary[KEY_STATISTICS_TIME] = [NSNumber numberWithInt: [statistics getTime]];
|
|
dictionary[KEY_STATISTICS_BITRATE] = [NSNumber numberWithDouble: [statistics getBitrate]];
|
|
dictionary[KEY_STATISTICS_SPEED] = [NSNumber numberWithDouble: [statistics getSpeed]];
|
|
|
|
return dictionary;
|
|
} else {
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
+ (NSDictionary*)toMediaInformationDictionary:(MediaInformation*)mediaInformation {
|
|
if (mediaInformation != nil) {
|
|
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
|
|
|
NSDictionary* allProperties = [mediaInformation getAllProperties];
|
|
if (allProperties != nil) {
|
|
for(NSString *key in [allProperties allKeys]) {
|
|
dictionary[key] = [allProperties objectForKey:key];
|
|
}
|
|
}
|
|
|
|
return dictionary;
|
|
} else {
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
+ (NSArray*)toLogArray:(NSArray*)logs {
|
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
|
|
|
for (int i = 0; i < [logs count]; i++) {
|
|
Log* log = [logs objectAtIndex:i];
|
|
[array addObject: [FFmpegKitFlutterPlugin toLogDictionary:log]];
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSArray*)toStatisticsArray:(NSArray*)statisticsArray {
|
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
|
|
|
for (int i = 0; i < [statisticsArray count]; i++) {
|
|
Statistics* statistics = [statisticsArray objectAtIndex:i];
|
|
[array addObject: [FFmpegKitFlutterPlugin toStatisticsDictionary:statistics]];
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSArray*)toSessionArray:(NSArray*)sessions {
|
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
|
|
|
for (int i = 0; i < [sessions count]; i++) {
|
|
AbstractSession* session = (AbstractSession*)[sessions objectAtIndex:i];
|
|
[array addObject: [FFmpegKitFlutterPlugin toSessionDictionary:session]];
|
|
}
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSDictionary *)toStringDictionary:(NSString*)key withDictionary:(NSDictionary*)value {
|
|
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
|
dictionary[key] = value;
|
|
|
|
return dictionary;
|
|
}
|
|
|
|
+ (NSNumber*)sessionStateToNumber:(SessionState)sessionState {
|
|
switch (sessionState) {
|
|
case SessionStateCreated:
|
|
return [NSNumber numberWithInt:0];
|
|
case SessionStateRunning:
|
|
return [NSNumber numberWithInt:1];
|
|
case SessionStateFailed:
|
|
return [NSNumber numberWithInt:2];
|
|
case SessionStateCompleted:
|
|
default:
|
|
return [NSNumber numberWithInt:3];
|
|
}
|
|
}
|
|
|
|
+ (NSNumber*)logRedirectionStrategyToNumber:(LogRedirectionStrategy)logRedirectionStrategy {
|
|
switch (logRedirectionStrategy) {
|
|
case LogRedirectionStrategyAlwaysPrintLogs:
|
|
return [NSNumber numberWithInt:0];
|
|
case LogRedirectionStrategyPrintLogsWhenNoCallbacksDefined:
|
|
return [NSNumber numberWithInt:1];
|
|
case LogRedirectionStrategyPrintLogsWhenGlobalCallbackNotDefined:
|
|
return [NSNumber numberWithInt:2];
|
|
case LogRedirectionStrategyPrintLogsWhenSessionCallbackNotDefined:
|
|
return [NSNumber numberWithInt:3];
|
|
case LogRedirectionStrategyNeverPrintLogs:
|
|
default:
|
|
return [NSNumber numberWithInt:4];
|
|
}
|
|
}
|
|
|
|
+ (BOOL)isValidPositiveNumber:(NSNumber*)value {
|
|
if (![value isEqual:[NSNull null]] && (value != nil) && ([value intValue] >= 0)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@end
|
|
|