FFmpegKit iOS / macOS / tvOS API 5.1
AbstractSession.m
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021-2022 Taner Sener
3 *
4 * This file is part of FFmpegKit.
5 *
6 * FFmpegKit is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * FFmpegKit is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General License
17 * along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#import "AbstractSession.h"
21#import "AtomicLong.h"
22#import "FFmpegKit.h"
23#import "FFmpegKitConfig.h"
24#import "LogCallback.h"
25#import "ReturnCode.h"
26
28
30
31extern void addSessionToSessionHistory(id<Session> session);
32
33@implementation AbstractSession {
34 long _sessionId;
36 NSDate* _createTime;
37 NSDate* _startTime;
38 NSDate* _endTime;
39 NSArray* _arguments;
40 NSMutableArray* _logs;
41 NSRecursiveLock* _logsLock;
42 SessionState _state;
44 NSString* _failStackTrace;
45 LogRedirectionStrategy _logRedirectionStrategy;
46}
47
48+ (void)initialize {
49 sessionIdGenerator = [[AtomicLong alloc] initWithValue:1];
50}
51
52- (instancetype)init:(NSArray*)arguments withLogCallback:(LogCallback)logCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {
53 self = [super init];
54 if (self) {
55 _sessionId = [sessionIdGenerator getAndIncrement];
57 _createTime = [NSDate date];
58 _startTime = nil;
59 _endTime = nil;
60 _arguments = arguments;
61 _logs = [[NSMutableArray alloc] init];
62 _logsLock = [[NSRecursiveLock alloc] init];
63 _state = SessionStateCreated;
64 _returnCode = nil;
65 _failStackTrace = nil;
66 _logRedirectionStrategy = logRedirectionStrategy;
67
69 }
70
71 return self;
72}
73
74- (LogCallback)getLogCallback {
75 return _logCallback;
76}
77
78- (long)getSessionId {
79 return _sessionId;
80}
81
82- (NSDate*)getCreateTime {
83 return _createTime;
84}
85
86- (NSDate*)getStartTime {
87 return _startTime;
88}
89
90- (NSDate*)getEndTime {
91 return _endTime;
92}
93
94- (long)getDuration {
95 NSDate* startTime = _startTime;
96 NSDate* endTime = _endTime;
97 if (startTime != nil && endTime != nil) {
98 return [[NSNumber numberWithDouble:([endTime timeIntervalSinceDate:startTime]*1000)] longValue];
99 }
100
101 return 0;
102}
103
104- (NSArray*)getArguments {
105 return _arguments;
106}
107
108- (NSString*)getCommand {
109 return [FFmpegKitConfig argumentsToString:_arguments];
110}
111
112- (void)waitForAsynchronousMessagesInTransmit:(int)timeout {
113 NSDate* expireDate = [[NSDate date] dateByAddingTimeInterval:((double)timeout)/1000];
114 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
115
116 while ([self thereAreAsynchronousMessagesInTransmit] && ([[NSDate date] timeIntervalSinceDate:expireDate] < 0)) {
117 dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC));
118 }
119}
120
121- (NSArray*)getAllLogsWithTimeout:(int)waitTimeout {
122 [self waitForAsynchronousMessagesInTransmit:waitTimeout];
123
124 if ([self thereAreAsynchronousMessagesInTransmit]) {
125 NSLog(@"getAllLogsWithTimeout was called to return all logs but there are still logs being transmitted for session id %ld.", _sessionId);
126 }
127
128 return [self getLogs];
129}
130
131- (NSArray*)getAllLogs {
132 return [self getAllLogsWithTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
133}
134
135- (NSArray*)getLogs {
136 [_logsLock lock];
137 NSArray* logsCopy = [_logs copy];
138 [_logsLock unlock];
139
140 return logsCopy;
141}
142
143- (NSString*)getAllLogsAsStringWithTimeout:(int)waitTimeout {
144 [self waitForAsynchronousMessagesInTransmit:waitTimeout];
145
146 if ([self thereAreAsynchronousMessagesInTransmit]) {
147 NSLog(@"getAllLogsAsStringWithTimeout was called to return all logs but there are still logs being transmitted for session id %ld.", _sessionId);
148 }
149
150 return [self getLogsAsString];
151}
152
153- (NSString*)getAllLogsAsString {
154 return [self getAllLogsAsStringWithTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
155}
156
157- (NSString*)getLogsAsString {
158 NSMutableString* concatenatedString = [[NSMutableString alloc] init];
159
160 [_logsLock lock];
161 for (int i=0; i < [_logs count]; i++) {
162 [concatenatedString appendString:[[_logs objectAtIndex:i] getMessage]];
163 }
164 [_logsLock unlock];
165
166 return concatenatedString;
167}
168
169- (NSString*)getOutput {
170 return [self getAllLogsAsString];
171}
172
173- (SessionState)getState {
174 return _state;
175}
176
177- (ReturnCode*)getReturnCode {
178 return _returnCode;
179}
180
181- (NSString*)getFailStackTrace {
182 return _failStackTrace;
183}
184
185- (LogRedirectionStrategy)getLogRedirectionStrategy {
187}
188
189- (BOOL)thereAreAsynchronousMessagesInTransmit {
190 return ([FFmpegKitConfig messagesInTransmit:_sessionId] != 0);
191}
192
193- (void)addLog:(Log*)log {
194 [_logsLock lock];
195 [_logs addObject:log];
196 [_logsLock unlock];
197}
198
199- (void)startRunning {
200 _state = SessionStateRunning;
201 _startTime = [NSDate date];
202}
203
204- (void)complete:(ReturnCode*)returnCode {
205 _returnCode = returnCode;
206 _state = SessionStateCompleted;
207 _endTime = [NSDate date];
208}
209
210- (void)fail:(NSException*)exception {
211 _failStackTrace = [NSString stringWithFormat:@"%@\n%@", [exception userInfo], [exception callStackSymbols]];
212 _state = SessionStateFailed;
213 _endTime = [NSDate date];
214}
215
216- (BOOL)isFFmpeg {
217 // IMPLEMENTED IN SUBCLASSES
218 return false;
219}
220
221- (BOOL)isFFprobe {
222 // IMPLEMENTED IN SUBCLASSES
223 return false;
224}
225
226- (BOOL)isMediaInformation {
227 // IMPLEMENTED IN SUBCLASSES
228 return false;
229}
230
231- (void)cancel {
232 if (_state == SessionStateRunning) {
233 [FFmpegKit cancel:_sessionId];
234 }
235}
236
237@end
NSString * _failStackTrace
NSRecursiveLock * _logsLock
NSDate * _endTime
NSArray * _arguments
SessionState _state
LogRedirectionStrategy _logRedirectionStrategy
NSDate * _startTime
int const AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit
NSDate * _createTime
static AtomicLong * sessionIdGenerator
ReturnCode * _returnCode
LogCallback _logCallback
NSMutableArray * _logs
void addSessionToSessionHistory(id< Session > session)
static LogCallback logCallback
long _sessionId
static dispatch_semaphore_t semaphore
void(^ LogCallback)(Log *log)
Definition: LogCallback.h:31
long getAndIncrement()
Definition: AtomicLong.m:40
NSString * argumentsToString:(NSArray *arguments)
void cancel:(long sessionId)
Definition: FFmpegKit.m:106
Definition: Log.h:29