2727import java .io .FileDescriptor ;
2828import java .io .FileInputStream ;
2929import java .io .IOException ;
30+ import java .util .concurrent .Callable ;
31+ import java .util .concurrent .Future ;
3032import java .util .concurrent .LinkedBlockingQueue ;
3133import java .util .concurrent .ThreadFactory ;
3234import java .util .concurrent .ThreadPoolExecutor ;
3335import java .util .concurrent .TimeUnit ;
36+ import java .util .concurrent .atomic .AtomicReference ;
3437
3538public class MediaTranscoder {
3639 private static final String TAG = "MediaTranscoder" ;
@@ -71,8 +74,8 @@ public static MediaTranscoder getInstance() {
7174 * @deprecated Use {@link #transcodeVideo(FileDescriptor, String, MediaFormatStrategy, MediaTranscoder.Listener)} which accepts output video format.
7275 */
7376 @ 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 () {
7679 @ Override
7780 public MediaFormat createVideoOutputFormat (MediaFormat inputFormat ) {
7881 return MediaFormatPresets .getExportPreset960x540 ();
@@ -95,7 +98,7 @@ public MediaFormat createAudioOutputFormat(MediaFormat inputFormat) {
9598 * @param listener Listener instance for callback.
9699 * @throws IOException if input file could not be read.
97100 */
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 {
99102 FileInputStream fileInputStream = null ;
100103 FileDescriptor inFileDescriptor ;
101104 try {
@@ -112,7 +115,7 @@ public void transcodeVideo(final String inPath, final String outPath, final Medi
112115 throw e ;
113116 }
114117 final FileInputStream finalFileInputStream = fileInputStream ;
115- transcodeVideo (inFileDescriptor , outPath , outFormatStrategy , new Listener () {
118+ return transcodeVideo (inFileDescriptor , outPath , outFormatStrategy , new Listener () {
116119 @ Override
117120 public void onTranscodeProgress (double progress ) {
118121 listener .onTranscodeProgress (progress );
@@ -124,6 +127,12 @@ public void onTranscodeCompleted() {
124127 closeStream ();
125128 }
126129
130+ @ Override
131+ public void onTranscodeCanceled () {
132+ listener .onTranscodeCanceled ();
133+ closeStream ();
134+ }
135+
127136 @ Override
128137 public void onTranscodeFailed (Exception exception ) {
129138 listener .onTranscodeFailed (exception );
@@ -149,13 +158,14 @@ private void closeStream() {
149158 * @param outFormatStrategy Strategy for output video format.
150159 * @param listener Listener instance for callback.
151160 */
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 ) {
153162 Looper looper = Looper .myLooper ();
154163 if (looper == null ) looper = Looper .getMainLooper ();
155164 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 >() {
157167 @ Override
158- public void run () {
168+ public Void call () throws Exception {
159169 Exception caughtException = null ;
160170 try {
161171 MediaTranscoderEngine engine = new MediaTranscoderEngine ();
@@ -176,6 +186,9 @@ public void run() {
176186 Log .w (TAG , "Transcode failed: input file (fd: " + inFileDescriptor .toString () + ") not found"
177187 + " or could not open output file ('" + outPath + "') ." , e );
178188 caughtException = e ;
189+ } catch (InterruptedException e ) {
190+ Log .i (TAG , "Cancel transcode video file." , e );
191+ caughtException = e ;
179192 } catch (RuntimeException e ) {
180193 Log .e (TAG , "Fatal error while transcoding, this might be invalid format or bug in engine or Android." , e );
181194 caughtException = e ;
@@ -188,12 +201,22 @@ public void run() {
188201 if (exception == null ) {
189202 listener .onTranscodeCompleted ();
190203 } 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+ }
192210 }
193211 }
194212 });
213+
214+ if (exception != null ) throw exception ;
215+ return null ;
195216 }
196217 });
218+ futureReference .set (createdFuture );
219+ return createdFuture ;
197220 }
198221
199222 public interface Listener {
@@ -209,6 +232,11 @@ public interface Listener {
209232 */
210233 void onTranscodeCompleted ();
211234
235+ /**
236+ * Called when transcode canceled.
237+ */
238+ void onTranscodeCanceled ();
239+
212240 /**
213241 * Called when transcode failed.
214242 *
0 commit comments