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.
237 lines
6.1 KiB
237 lines
6.1 KiB
/*
|
|
* Copyright (c) 2021-2022 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 "FFmpegKit.h"
|
|
#import "FFmpegKitConfig.h"
|
|
#import "LogCallback.h"
|
|
#import "ReturnCode.h"
|
|
|
|
int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit = 5000;
|
|
|
|
static AtomicLong *sessionIdGenerator = nil;
|
|
|
|
extern void addSessionToSessionHistory(id<Session> session);
|
|
|
|
@implementation AbstractSession {
|
|
long _sessionId;
|
|
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 withLogCallback:(LogCallback)logCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {
|
|
self = [super init];
|
|
if (self) {
|
|
_sessionId = [sessionIdGenerator getAndIncrement];
|
|
_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;
|
|
|
|
addSessionToSessionHistory(self);
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (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 [FFmpegKitConfig 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:@"%@\n%@", [exception userInfo], [exception callStackSymbols]];
|
|
_state = SessionStateFailed;
|
|
_endTime = [NSDate date];
|
|
}
|
|
|
|
- (BOOL)isFFmpeg {
|
|
// IMPLEMENTED IN SUBCLASSES
|
|
return false;
|
|
}
|
|
|
|
- (BOOL)isFFprobe {
|
|
// IMPLEMENTED IN SUBCLASSES
|
|
return false;
|
|
}
|
|
|
|
- (BOOL)isMediaInformation {
|
|
// IMPLEMENTED IN SUBCLASSES
|
|
return false;
|
|
}
|
|
|
|
- (void)cancel {
|
|
if (_state == SessionStateRunning) {
|
|
[FFmpegKit cancel:_sessionId];
|
|
}
|
|
}
|
|
|
|
@end
|
|
|