27
27
import java .io .FileDescriptor ;
28
28
import java .io .FileInputStream ;
29
29
import java .io .IOException ;
30
+ import java .util .concurrent .Callable ;
31
+ import java .util .concurrent .Future ;
30
32
import java .util .concurrent .LinkedBlockingQueue ;
31
33
import java .util .concurrent .ThreadFactory ;
32
34
import java .util .concurrent .ThreadPoolExecutor ;
33
35
import java .util .concurrent .TimeUnit ;
36
+ import java .util .concurrent .atomic .AtomicReference ;
34
37
35
38
public class MediaTranscoder {
36
39
private static final String TAG = "MediaTranscoder" ;
@@ -71,8 +74,8 @@ public static MediaTranscoder getInstance() {
71
74
* @deprecated Use {@link #transcodeVideo(FileDescriptor, String, MediaFormatStrategy, MediaTranscoder.Listener)} which accepts output video format.
72
75
*/
73
76
@ Deprecated
74
- public void transcodeVideo (final FileDescriptor inFileDescriptor , final String outPath , final Listener listener ) {
75
- transcodeVideo (inFileDescriptor , outPath , new MediaFormatStrategy () {
77
+ public Future transcodeVideo (final FileDescriptor inFileDescriptor , final String outPath , final Listener listener ) {
78
+ return transcodeVideo (inFileDescriptor , outPath , new MediaFormatStrategy () {
76
79
@ Override
77
80
public MediaFormat createVideoOutputFormat (MediaFormat inputFormat ) {
78
81
return MediaFormatPresets .getExportPreset960x540 ();
@@ -95,7 +98,7 @@ public MediaFormat createAudioOutputFormat(MediaFormat inputFormat) {
95
98
* @param listener Listener instance for callback.
96
99
* @throws IOException if input file could not be read.
97
100
*/
98
- public void transcodeVideo (final String inPath , final String outPath , final MediaFormatStrategy outFormatStrategy , final Listener listener ) throws IOException {
101
+ public Future transcodeVideo (final String inPath , final String outPath , final MediaFormatStrategy outFormatStrategy , final Listener listener ) throws IOException {
99
102
FileInputStream fileInputStream = null ;
100
103
FileDescriptor inFileDescriptor ;
101
104
try {
@@ -112,7 +115,7 @@ public void transcodeVideo(final String inPath, final String outPath, final Medi
112
115
throw e ;
113
116
}
114
117
final FileInputStream finalFileInputStream = fileInputStream ;
115
- transcodeVideo (inFileDescriptor , outPath , outFormatStrategy , new Listener () {
118
+ return transcodeVideo (inFileDescriptor , outPath , outFormatStrategy , new Listener () {
116
119
@ Override
117
120
public void onTranscodeProgress (double progress ) {
118
121
listener .onTranscodeProgress (progress );
@@ -124,6 +127,12 @@ public void onTranscodeCompleted() {
124
127
closeStream ();
125
128
}
126
129
130
+ @ Override
131
+ public void onTranscodeCanceled () {
132
+ listener .onTranscodeCanceled ();
133
+ closeStream ();
134
+ }
135
+
127
136
@ Override
128
137
public void onTranscodeFailed (Exception exception ) {
129
138
listener .onTranscodeFailed (exception );
@@ -149,13 +158,14 @@ private void closeStream() {
149
158
* @param outFormatStrategy Strategy for output video format.
150
159
* @param listener Listener instance for callback.
151
160
*/
152
- public void transcodeVideo (final FileDescriptor inFileDescriptor , final String outPath , final MediaFormatStrategy outFormatStrategy , final Listener listener ) {
161
+ public Future transcodeVideo (final FileDescriptor inFileDescriptor , final String outPath , final MediaFormatStrategy outFormatStrategy , final Listener listener ) {
153
162
Looper looper = Looper .myLooper ();
154
163
if (looper == null ) looper = Looper .getMainLooper ();
155
164
final Handler handler = new Handler (looper );
156
- mExecutor .execute (new Runnable () {
165
+ final AtomicReference <Future > futureReference = new AtomicReference <>();
166
+ final Future <Void > createdFuture = mExecutor .submit (new Callable <Void >() {
157
167
@ Override
158
- public void run () {
168
+ public Void call () throws Exception {
159
169
Exception caughtException = null ;
160
170
try {
161
171
MediaTranscoderEngine engine = new MediaTranscoderEngine ();
@@ -176,6 +186,9 @@ public void run() {
176
186
Log .w (TAG , "Transcode failed: input file (fd: " + inFileDescriptor .toString () + ") not found"
177
187
+ " or could not open output file ('" + outPath + "') ." , e );
178
188
caughtException = e ;
189
+ } catch (InterruptedException e ) {
190
+ Log .i (TAG , "Cancel transcode video file." , e );
191
+ caughtException = e ;
179
192
} catch (RuntimeException e ) {
180
193
Log .e (TAG , "Fatal error while transcoding, this might be invalid format or bug in engine or Android." , e );
181
194
caughtException = e ;
@@ -188,12 +201,22 @@ public void run() {
188
201
if (exception == null ) {
189
202
listener .onTranscodeCompleted ();
190
203
} else {
191
- listener .onTranscodeFailed (exception );
204
+ Future future = futureReference .get ();
205
+ if (future != null && future .isCancelled ()) {
206
+ listener .onTranscodeCanceled ();
207
+ } else {
208
+ listener .onTranscodeFailed (exception );
209
+ }
192
210
}
193
211
}
194
212
});
213
+
214
+ if (exception != null ) throw exception ;
215
+ return null ;
195
216
}
196
217
});
218
+ futureReference .set (createdFuture );
219
+ return createdFuture ;
197
220
}
198
221
199
222
public interface Listener {
@@ -209,6 +232,11 @@ public interface Listener {
209
232
*/
210
233
void onTranscodeCompleted ();
211
234
235
+ /**
236
+ * Called when transcode canceled.
237
+ */
238
+ void onTranscodeCanceled ();
239
+
212
240
/**
213
241
* Called when transcode failed.
214
242
*
0 commit comments