AbstractSession.m
Go to the documentation of this file.
/*
* 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 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 License for more details.
*
* You should have received a copy of the GNU Lesser General License
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
*/
#import "AbstractSession.h"
#import "AtomicLong.h"
#import "ExecuteCallback.h"
#import "FFmpegKit.h"
#import "FFmpegKitConfig.h"
#import "LogCallback.h"
#import "ReturnCode.h"
int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit = 5000;
static AtomicLong *sessionIdGenerator = nil;
@implementation AbstractSession {
long _sessionId;
ExecuteCallback _executeCallback;
LogCallback _logCallback;
NSDate* _createTime;
NSDate* _startTime;
NSDate* _endTime;
NSArray* _arguments;
NSMutableArray* _logs;
NSRecursiveLock* _logsLock;
SessionState _state;
ReturnCode* _returnCode;
NSString* _failStackTrace;
LogRedirectionStrategy _logRedirectionStrategy;
}
+ (void)initialize {
sessionIdGenerator = [[AtomicLong alloc] initWithValue:1];
}
- (instancetype)init:(NSArray*)arguments withExecuteCallback:(ExecuteCallback)executeCallback withLogCallback:(LogCallback)logCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {
self = [super init];
if (self) {
_sessionId = [sessionIdGenerator getAndIncrement];
_executeCallback = executeCallback;
_logCallback = logCallback;
_createTime = [NSDate date];
_startTime = nil;
_endTime = nil;
_arguments = arguments;
_logs = [[NSMutableArray alloc] init];
_logsLock = [[NSRecursiveLock alloc] init];
_state = SessionStateCreated;
_returnCode = nil;
_failStackTrace = nil;
_logRedirectionStrategy = logRedirectionStrategy;
}
return self;
}
- (ExecuteCallback)getExecuteCallback {
return _executeCallback;
}
- (LogCallback)getLogCallback {
return _logCallback;
}
- (long)getSessionId {
return _sessionId;
}
- (NSDate*)getCreateTime {
return _createTime;
}
- (NSDate*)getStartTime {
return _startTime;
}
- (NSDate*)getEndTime {
return _endTime;
}
- (long)getDuration {
NSDate* startTime = _startTime;
NSDate* endTime = _endTime;
if (startTime != nil && endTime != nil) {
return [[NSNumber numberWithDouble:([endTime timeIntervalSinceDate:startTime]*1000)] longValue];
}
return 0;
}
- (NSArray*)getArguments {
return _arguments;
}
- (NSString*)getCommand {
return [FFmpegKit argumentsToString:_arguments];
}
- (void)waitForAsynchronousMessagesInTransmit:(int)timeout {
NSDate* expireDate = [[NSDate date] dateByAddingTimeInterval:((double)timeout)/1000];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
while ([self thereAreAsynchronousMessagesInTransmit] && ([[NSDate date] timeIntervalSinceDate:expireDate] < 0)) {
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC));
}
}
- (NSArray*)getAllLogsWithTimeout:(int)waitTimeout {
[self waitForAsynchronousMessagesInTransmit:waitTimeout];
if ([self thereAreAsynchronousMessagesInTransmit]) {
NSLog(@"getAllLogsWithTimeout was called to return all logs but there are still logs being transmitted for session id %ld.", _sessionId);
}
return [self getLogs];
}
- (NSArray*)getAllLogs {
return [self getAllLogsWithTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
}
- (NSArray*)getLogs {
[_logsLock lock];
NSArray* logsCopy = [_logs copy];
[_logsLock unlock];
return logsCopy;
}
- (NSString*)getAllLogsAsStringWithTimeout:(int)waitTimeout {
[self waitForAsynchronousMessagesInTransmit:waitTimeout];
if ([self thereAreAsynchronousMessagesInTransmit]) {
NSLog(@"getAllLogsAsStringWithTimeout was called to return all logs but there are still logs being transmitted for session id %ld.", _sessionId);
}
return [self getLogsAsString];
}
- (NSString*)getAllLogsAsString {
return [self getAllLogsAsStringWithTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
}
- (NSString*)getLogsAsString {
NSMutableString* concatenatedString = [[NSMutableString alloc] init];
[_logsLock lock];
for (int i=0; i < [_logs count]; i++) {
[concatenatedString appendString:[[_logs objectAtIndex:i] getMessage]];
}
[_logsLock unlock];
return concatenatedString;
}
- (NSString*)getOutput {
return [self getAllLogsAsString];
}
- (SessionState)getState {
return _state;
}
- (ReturnCode*)getReturnCode {
return _returnCode;
}
- (NSString*)getFailStackTrace {
return _failStackTrace;
}
- (LogRedirectionStrategy)getLogRedirectionStrategy {
return _logRedirectionStrategy;
}
- (BOOL)thereAreAsynchronousMessagesInTransmit {
return ([FFmpegKitConfig messagesInTransmit:_sessionId] != 0);
}
- (void)addLog:(Log*)log {
[_logsLock lock];
[_logs addObject:log];
[_logsLock unlock];
}
- (void)startRunning {
_state = SessionStateRunning;
_startTime = [NSDate date];
}
- (void)complete:(ReturnCode*)returnCode {
_returnCode = returnCode;
_state = SessionStateCompleted;
_endTime = [NSDate date];
}
- (void)fail:(NSException*)exception {
_failStackTrace = [NSString stringWithFormat:@"%@", [exception callStackSymbols]];
_state = SessionStateFailed;
_endTime = [NSDate date];
}
- (BOOL)isFFmpeg {
// IMPLEMENTED IN SUBCLASSES
return false;
}
- (BOOL)isFFprobe {
// IMPLEMENTED IN SUBCLASSES
return false;
}
- (void)cancel {
if (_state == SessionStateRunning) {
[FFmpegKit cancel:_sessionId];
}
}
@end
AbstractSession.h
_executeCallback
ExecuteCallback _executeCallback
Definition: AbstractSession.m:32
_failStackTrace
NSString * _failStackTrace
Definition: AbstractSession.m:44
_logsLock
NSRecursiveLock * _logsLock
Definition: AbstractSession.m:41
_endTime
NSDate * _endTime
Definition: AbstractSession.m:38
_arguments
NSArray * _arguments
Definition: AbstractSession.m:39
_state
SessionState _state
Definition: AbstractSession.m:42
_logRedirectionStrategy
LogRedirectionStrategy _logRedirectionStrategy
Definition: AbstractSession.m:45
_startTime
NSDate * _startTime
Definition: AbstractSession.m:37
AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit
int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit
Definition: AbstractSession.m:28
_createTime
NSDate * _createTime
Definition: AbstractSession.m:36
sessionIdGenerator
static AtomicLong * sessionIdGenerator
Definition: AbstractSession.m:30
_returnCode
ReturnCode * _returnCode
Definition: AbstractSession.m:43
_logCallback
LogCallback _logCallback
Definition: AbstractSession.m:35
_logs
NSMutableArray * _logs
Definition: AbstractSession.m:40
AtomicLong.h
ExecuteCallback.h
ExecuteCallback
void(^ ExecuteCallback)(id< Session > session)
Definition: ExecuteCallback.h:46
FFmpegKit.h
FFmpegKitConfig.h
logCallback
static LogCallback logCallback
Definition: FFmpegKitConfig.m:64
_sessionId
__thread volatile long _sessionId
Definition: FFmpegKitConfig.m:88
executeCallback
static ExecuteCallback executeCallback
Definition: FFmpegKitConfig.m:70
semaphore
static dispatch_semaphore_t semaphore
Definition: FFmpegKitConfig.m:77
LogCallback.h
LogCallback
void(^ LogCallback)(Log *log)
Definition: LogCallback.h:31
ReturnCode.h
AbstractSession
Definition: AbstractSession.h:35
AtomicLong
Definition: AtomicLong.h:29
-[AtomicLong getAndIncrement]
long getAndIncrement()
Definition: AtomicLong.m:40
FFmpegKitConfig
Definition: FFmpegKitConfig.h:50
FFmpegKit
Definition: FFmpegKit.h:45
+[FFmpegKit cancel:]
void cancel:(long sessionId)
Definition: FFmpegKit.m:106
+[FFmpegKit argumentsToString:]
NSString * argumentsToString:(NSArray *arguments)
Definition: FFmpegKit.m:165
Log
Definition: Log.h:29
ReturnCode
Definition: ReturnCode.h:31