react-native-compressor 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/README.md +36 -1
  2. package/android/build.gradle +0 -1
  3. package/android/src/main/java/com/reactnativecompressor/.DS_Store +0 -0
  4. package/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.java +3 -3
  5. package/android/src/main/java/com/reactnativecompressor/CompressorModule.java +5 -1
  6. package/android/src/main/java/com/reactnativecompressor/Utils/Utils.java +74 -0
  7. package/android/src/main/java/com/reactnativecompressor/Video/.DS_Store +0 -0
  8. package/android/src/main/java/com/reactnativecompressor/Video/AutoVideoCompression/AutoVideoCompression.java +3 -37
  9. package/android/src/main/java/com/reactnativecompressor/Video/VideoCompressorHelper.java +2 -38
  10. package/android/src/main/java/com/reactnativecompressor/Video/VideoModule.java +9 -7
  11. package/android/src/main/java/com/reactnativecompressor/Video/videoslimmer/VideoSlimEncoder.java +629 -0
  12. package/android/src/main/java/com/reactnativecompressor/Video/videoslimmer/VideoSlimTask.java +59 -0
  13. package/android/src/main/java/com/reactnativecompressor/Video/videoslimmer/VideoSlimmer.java +20 -0
  14. package/android/src/main/java/com/reactnativecompressor/Video/videoslimmer/listner/SlimProgressListener.java +6 -0
  15. package/android/src/main/java/com/reactnativecompressor/Video/videoslimmer/muxer/CodecInputSurface.java +202 -0
  16. package/android/src/main/java/com/reactnativecompressor/Video/videoslimmer/render/TextureRenderer.java +196 -0
  17. package/ios/Compressor.m +2 -0
  18. package/ios/Video/VideoCompressor.swift +20 -11
  19. package/lib/commonjs/Video/index.js +12 -1
  20. package/lib/commonjs/Video/index.js.map +1 -1
  21. package/lib/module/Video/index.js +8 -0
  22. package/lib/module/Video/index.js.map +1 -1
  23. package/lib/typescript/Video/index.d.ts +3 -0
  24. package/package.json +1 -1
  25. package/src/Video/index.tsx +11 -6
@@ -0,0 +1,629 @@
1
+ package com.reactnativecompressor.Video.videoslimmer;
2
+
3
+ import android.media.MediaCodec;
4
+ import android.media.MediaCodecInfo;
5
+ import android.media.MediaExtractor;
6
+ import android.media.MediaFormat;
7
+ import android.media.MediaMetadataRetriever;
8
+ import android.media.MediaMuxer;
9
+ import android.media.MediaPlayer;
10
+ import android.os.Build;
11
+ import android.util.Log;
12
+ import android.view.Surface;
13
+
14
+ import com.reactnativecompressor.Video.videoslimmer.listner.SlimProgressListener;
15
+ import com.reactnativecompressor.Video.videoslimmer.muxer.CodecInputSurface;
16
+
17
+ import java.io.File;
18
+ import java.io.IOException;
19
+ import java.nio.ByteBuffer;
20
+
21
+ public class VideoSlimEncoder {
22
+
23
+ private static final String TAG = "VideoSlimEncoder";
24
+ private static final boolean VERBOSE = true; // lots of logging
25
+ public String path;
26
+ private String outputPath;
27
+ public final static String MIME_TYPE = "video/avc";
28
+ private MediaCodec.BufferInfo mBufferInfo;
29
+ private MediaMuxer mMuxer;
30
+ private MediaCodec mEncoder;
31
+ private MediaCodec mDecoder;
32
+ private int mTrackIndex;
33
+ private CodecInputSurface mInputSurface;
34
+ // size of a frame, in pixels
35
+ private int mWidth = -1;
36
+ private int mHeight = -1;
37
+ // bit rate, in bits per second
38
+ private int mBitRate = -1;
39
+ private static int FRAME_RATE = 25; // 15fps
40
+ private static int IFRAME_INTERVAL = 10; // 10 seconds between I-frames
41
+ private static final int MEDIATYPE_NOT_AUDIO_VIDEO = -233;
42
+ private final int TIMEOUT_USEC = 2500;
43
+
44
+ public VideoSlimEncoder () {
45
+
46
+ }
47
+
48
+
49
+ /***
50
+ * trans video and audio by mediacodec
51
+ *
52
+ * */
53
+ public boolean convertVideo(final String sourcePath, String destinationPath, int nwidth, int nheight, int nbitrate, SlimProgressListener listener) {
54
+
55
+ this.path = sourcePath;
56
+ this.outputPath = destinationPath;
57
+
58
+ if (checkParmsError(sourcePath, destinationPath, nwidth, nheight, nbitrate)) {
59
+ return false;
60
+ }
61
+
62
+ //get origin video info
63
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
64
+ retriever.setDataSource(path);
65
+ String width = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
66
+ String height = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
67
+ String rotation = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
68
+ // String framecount = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT);
69
+ long duration = Long.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) * 1000;
70
+
71
+ long startTime = -1;
72
+ long endTime = -1;
73
+
74
+ int originalWidth = Integer.valueOf(width);
75
+ int originalHeight = Integer.valueOf(height);
76
+
77
+ mBitRate = nbitrate;
78
+ mWidth = nwidth;
79
+ mHeight = nheight;
80
+
81
+
82
+ // NUM_FRAMES = Integer.getInteger(framecount);
83
+ //IFRAME_INTERVAL = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
84
+
85
+
86
+ boolean error = false;
87
+ long videoStartTime = -1;
88
+
89
+ long time = System.currentTimeMillis();
90
+
91
+ File cacheFile = new File(destinationPath);
92
+ File inputFile = new File(path);
93
+ if (!inputFile.canRead()) {
94
+
95
+ return false;
96
+ }
97
+
98
+ MediaExtractor extractor = null;
99
+ MediaExtractor mAudioExtractor = null;
100
+
101
+ try {
102
+ // video MediaExtractor
103
+ extractor = new MediaExtractor();
104
+ extractor.setDataSource(inputFile.toString());
105
+
106
+ // audio MediaExtractor
107
+ mAudioExtractor = new MediaExtractor();
108
+ mAudioExtractor.setDataSource(inputFile.toString());
109
+ try {
110
+ mMuxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
111
+ } catch (IOException ioe) {
112
+
113
+
114
+ throw new RuntimeException("MediaMuxer creation failed", ioe);
115
+ }
116
+
117
+ int muxerAudioTrackIndex = 0;
118
+
119
+
120
+ int audioIndex = selectTrack(mAudioExtractor, true);
121
+ if (audioIndex >= 0) {
122
+ mAudioExtractor.selectTrack(audioIndex);
123
+ mAudioExtractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
124
+ MediaFormat trackFormat = mAudioExtractor.getTrackFormat(audioIndex);
125
+ muxerAudioTrackIndex = mMuxer.addTrack(trackFormat);
126
+
127
+ // extractor.unselectTrack(muxerAudioTrackIndex);
128
+ }
129
+
130
+ /**
131
+ * mediacodec + surface + opengl
132
+ * */
133
+ if (nwidth != originalWidth || nheight != originalHeight) {
134
+
135
+ int videoIndex = selectTrack(extractor, false);
136
+
137
+ if (videoIndex >= 0) {
138
+
139
+ long videoTime = -1;
140
+ boolean outputDone = false;
141
+ boolean inputDone = false;
142
+ boolean decoderDone = false;
143
+ int swapUV = 0;
144
+ int videoTrackIndex = MEDIATYPE_NOT_AUDIO_VIDEO;
145
+
146
+
147
+ extractor.selectTrack(videoIndex);
148
+ if (startTime > 0) {
149
+ extractor.seekTo(startTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
150
+ } else {
151
+ extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
152
+ }
153
+ MediaFormat inputFormat = extractor.getTrackFormat(videoIndex);
154
+
155
+
156
+ /**
157
+ ** init mediacodec / encoder and decoder
158
+ **/
159
+ prepareEncoder(inputFormat);
160
+
161
+
162
+ ByteBuffer[] decoderInputBuffers = null;
163
+ ByteBuffer[] encoderOutputBuffers = null;
164
+
165
+
166
+ decoderInputBuffers = mDecoder.getInputBuffers();
167
+ encoderOutputBuffers = mEncoder.getOutputBuffers();
168
+
169
+
170
+ while (!outputDone) {
171
+ if (!inputDone) {
172
+ boolean eof = false;
173
+ int index = extractor.getSampleTrackIndex();
174
+ if (index == videoIndex) {
175
+ int inputBufIndex = mDecoder.dequeueInputBuffer(TIMEOUT_USEC);
176
+ if (inputBufIndex >= 0) {
177
+ ByteBuffer inputBuf;
178
+ if (Build.VERSION.SDK_INT < 21) {
179
+ inputBuf = decoderInputBuffers[inputBufIndex];
180
+ } else {
181
+ inputBuf = mDecoder.getInputBuffer(inputBufIndex);
182
+ }
183
+ int chunkSize = extractor.readSampleData(inputBuf, 0);
184
+ if (chunkSize < 0) {
185
+ mDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
186
+ inputDone = true;
187
+ } else {
188
+ mDecoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.getSampleTime(), 0);
189
+ extractor.advance();
190
+ }
191
+ }
192
+ } else if (index == -1) {
193
+ eof = true;
194
+ }
195
+ if (eof) {
196
+ int inputBufIndex = mDecoder.dequeueInputBuffer(TIMEOUT_USEC);
197
+ if (inputBufIndex >= 0) {
198
+ mDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
199
+ inputDone = true;
200
+ }
201
+ }
202
+ }
203
+
204
+ boolean decoderOutputAvailable = !decoderDone;
205
+ boolean encoderOutputAvailable = true;
206
+
207
+ while (decoderOutputAvailable || encoderOutputAvailable) {
208
+
209
+ int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
210
+ if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
211
+ encoderOutputAvailable = false;
212
+ } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
213
+ if (Build.VERSION.SDK_INT < 21) {
214
+ encoderOutputBuffers = mEncoder.getOutputBuffers();
215
+ }
216
+ } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
217
+ MediaFormat newFormat = mEncoder.getOutputFormat();
218
+ if (videoTrackIndex == MEDIATYPE_NOT_AUDIO_VIDEO) {
219
+ videoTrackIndex = mMuxer.addTrack(newFormat);
220
+ mTrackIndex = videoTrackIndex;
221
+ mMuxer.start();
222
+ }
223
+ } else if (encoderStatus < 0) {
224
+ throw new RuntimeException("unexpected result from mEncoder.dequeueOutputBuffer: " + encoderStatus);
225
+ } else {
226
+ ByteBuffer encodedData;
227
+ if (Build.VERSION.SDK_INT < 21) {
228
+ encodedData = encoderOutputBuffers[encoderStatus];
229
+ } else {
230
+ encodedData = mEncoder.getOutputBuffer(encoderStatus);
231
+ }
232
+ if (encodedData == null) {
233
+ throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
234
+ }
235
+ if (mBufferInfo.size > 1) {
236
+ if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
237
+ mMuxer.writeSampleData(videoTrackIndex, encodedData, mBufferInfo);
238
+ } else if (videoTrackIndex == MEDIATYPE_NOT_AUDIO_VIDEO) {
239
+ byte[] csd = new byte[mBufferInfo.size];
240
+ encodedData.limit(mBufferInfo.offset + mBufferInfo.size);
241
+ encodedData.position(mBufferInfo.offset);
242
+ encodedData.get(csd);
243
+ ByteBuffer sps = null;
244
+ ByteBuffer pps = null;
245
+ for (int a = mBufferInfo.size - 1; a >= 0; a--) {
246
+ if (a > 3) {
247
+ if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) {
248
+ sps = ByteBuffer.allocate(a - 3);
249
+ pps = ByteBuffer.allocate(mBufferInfo.size - (a - 3));
250
+ sps.put(csd, 0, a - 3).position(0);
251
+ pps.put(csd, a - 3, mBufferInfo.size - (a - 3)).position(0);
252
+ break;
253
+ }
254
+ } else {
255
+ break;
256
+ }
257
+ }
258
+
259
+ MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, nwidth, nheight);
260
+ if (sps != null && pps != null) {
261
+ newFormat.setByteBuffer("csd-0", sps);
262
+ newFormat.setByteBuffer("csd-1", pps);
263
+ }
264
+ videoTrackIndex = mMuxer.addTrack(newFormat);
265
+ mMuxer.start();
266
+ }
267
+ }
268
+ outputDone = (mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
269
+ mEncoder.releaseOutputBuffer(encoderStatus, false);
270
+ }
271
+ if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) {
272
+ continue;
273
+ }
274
+
275
+ if (!decoderDone) {
276
+ int decoderStatus = mDecoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
277
+ if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
278
+ decoderOutputAvailable = false;
279
+ } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
280
+
281
+ } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
282
+ MediaFormat newFormat = mDecoder.getOutputFormat();
283
+ Log.e(TAG, "newFormat = " + newFormat);
284
+ } else if (decoderStatus < 0) {
285
+ throw new RuntimeException("unexpected result from mDecoder.dequeueOutputBuffer: " + decoderStatus);
286
+ } else {
287
+ boolean doRender = false;
288
+
289
+ doRender = mBufferInfo.size != 0;
290
+
291
+ if (endTime > 0 && mBufferInfo.presentationTimeUs >= endTime) {
292
+ inputDone = true;
293
+ decoderDone = true;
294
+ doRender = false;
295
+ mBufferInfo.flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
296
+ }
297
+ if (startTime > 0 && videoTime == -1) {
298
+ if (mBufferInfo.presentationTimeUs < startTime) {
299
+ doRender = false;
300
+ Log.e(TAG, "drop frame startTime = " + startTime + " present time = " + mBufferInfo.presentationTimeUs);
301
+ } else {
302
+ videoTime = mBufferInfo.presentationTimeUs;
303
+ }
304
+ }
305
+ mDecoder.releaseOutputBuffer(decoderStatus, doRender);
306
+ if (doRender) {
307
+ boolean errorWait = false;
308
+ try {
309
+ mInputSurface.awaitNewImage();
310
+ } catch (Exception e) {
311
+ errorWait = true;
312
+ if(e.getMessage().equals("java.lang.InterruptedException"))
313
+ {
314
+ return false;
315
+ }
316
+ Log.e(TAG, e.getMessage());
317
+ }
318
+ if (!errorWait) {
319
+
320
+ mInputSurface.drawImage();
321
+ mInputSurface.setPresentationTime(mBufferInfo.presentationTimeUs * 1000);
322
+
323
+ if (listener != null) {
324
+ listener.onProgress((float) mBufferInfo.presentationTimeUs / (float) duration * 100);
325
+ }
326
+
327
+ mInputSurface.swapBuffers();
328
+
329
+ }
330
+ }
331
+ if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
332
+ decoderOutputAvailable = false;
333
+ Log.e(TAG, "decoder stream end");
334
+
335
+ mEncoder.signalEndOfInputStream();
336
+
337
+ }
338
+ }
339
+ }
340
+ }
341
+ }
342
+ if (videoTime != -1) {
343
+ videoStartTime = videoTime;
344
+ }
345
+
346
+
347
+ }
348
+
349
+
350
+ extractor.unselectTrack(videoIndex);
351
+
352
+ } else {
353
+ Log.e(TAG,"startvideorecord");
354
+ long videoTime = simpleReadAndWriteTrack(extractor, mMuxer, mBufferInfo, startTime, endTime, cacheFile, false);
355
+ if (videoTime != -1) {
356
+ videoStartTime = videoTime;
357
+ }
358
+ }
359
+
360
+ // if (!error) {
361
+ // Log.e(TAG,"startaudiorecord");
362
+ // simpleReadAndWriteTrack(extractor, mMuxer, mBufferInfo, videoStartTime, endTime, cacheFile, true);
363
+ // }
364
+
365
+ writeAudioTrack(mAudioExtractor, mMuxer, mBufferInfo, videoStartTime, endTime, cacheFile, muxerAudioTrackIndex);
366
+
367
+ } catch (Exception e) {
368
+ error = true;
369
+ Log.e(TAG, e.getMessage());
370
+ } finally {
371
+ if (extractor != null) {
372
+ extractor.release();
373
+ extractor = null;
374
+ }
375
+
376
+
377
+ if (mAudioExtractor != null) {
378
+ mAudioExtractor.release();
379
+ mAudioExtractor = null;
380
+ }
381
+ Log.e(TAG, "time = " + (System.currentTimeMillis() - time));
382
+ }
383
+
384
+
385
+ Log.e("ViratPath", path + "");
386
+ Log.e("ViratPath", cacheFile.getPath() + "");
387
+ Log.e("ViratPath", inputFile.getPath() + "");
388
+
389
+
390
+
391
+ releaseCoder();
392
+
393
+ if(error)
394
+ return false;
395
+ else
396
+ return true;
397
+ }
398
+
399
+
400
+ private boolean checkParmsError(String sourcePath, String destinationPath, int nwidth, int nheight, int nbitrate) {
401
+
402
+
403
+ if (nwidth <= 0 || nheight <= 0 || nbitrate <= 0)
404
+ return true;
405
+ else
406
+ return false;
407
+
408
+ }
409
+
410
+
411
+ private long simpleReadAndWriteTrack(MediaExtractor extractor, MediaMuxer mediaMuxer, MediaCodec.BufferInfo info, long start, long end, File file, boolean isAudio) throws Exception {
412
+ int trackIndex = selectTrack(extractor, isAudio);
413
+ if (trackIndex >= 0) {
414
+ extractor.selectTrack(trackIndex);
415
+ MediaFormat trackFormat = extractor.getTrackFormat(trackIndex);
416
+ int muxerTrackIndex = mediaMuxer.addTrack(trackFormat);
417
+
418
+ if(!isAudio)
419
+ mediaMuxer.start();
420
+
421
+ int maxBufferSize = trackFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
422
+ boolean inputDone = false;
423
+ if (start > 0) {
424
+ extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
425
+ } else {
426
+ extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
427
+ }
428
+ ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
429
+ long startTime = -1;
430
+
431
+ while (!inputDone) {
432
+
433
+ boolean eof = false;
434
+ int index = extractor.getSampleTrackIndex();
435
+ if (index == trackIndex) {
436
+ info.size = extractor.readSampleData(buffer, 0);
437
+
438
+ if (info.size < 0) {
439
+ info.size = 0;
440
+ eof = true;
441
+ } else {
442
+ info.presentationTimeUs = extractor.getSampleTime();
443
+ if (start > 0 && startTime == -1) {
444
+ startTime = info.presentationTimeUs;
445
+ }
446
+ if (end < 0 || info.presentationTimeUs < end) {
447
+ info.offset = 0;
448
+ info.flags = extractor.getSampleFlags();
449
+ mediaMuxer.writeSampleData(muxerTrackIndex, buffer, info);
450
+ extractor.advance();
451
+ } else {
452
+ eof = true;
453
+ }
454
+ }
455
+ } else if (index == -1) {
456
+ eof = true;
457
+ }
458
+ if (eof) {
459
+ inputDone = true;
460
+ }
461
+ }
462
+
463
+ extractor.unselectTrack(trackIndex);
464
+ return startTime;
465
+ }
466
+ return -1;
467
+ }
468
+
469
+
470
+ private long writeAudioTrack(MediaExtractor extractor, MediaMuxer mediaMuxer, MediaCodec.BufferInfo info, long start, long end, File file,int muxerTrackIndex ) throws Exception {
471
+ int trackIndex = selectTrack(extractor, true);
472
+ if (trackIndex >= 0) {
473
+ extractor.selectTrack(trackIndex);
474
+ MediaFormat trackFormat = extractor.getTrackFormat(trackIndex);
475
+
476
+
477
+ int maxBufferSize = trackFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
478
+ boolean inputDone = false;
479
+ if (start > 0) {
480
+ extractor.seekTo(start, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
481
+ } else {
482
+ extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
483
+ }
484
+ ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
485
+ long startTime = -1;
486
+
487
+ while (!inputDone) {
488
+
489
+ boolean eof = false;
490
+ int index = extractor.getSampleTrackIndex();
491
+ if (index == trackIndex) {
492
+ info.size = extractor.readSampleData(buffer, 0);
493
+
494
+ if (info.size < 0) {
495
+ info.size = 0;
496
+ eof = true;
497
+ } else {
498
+ info.presentationTimeUs = extractor.getSampleTime();
499
+ if (start > 0 && startTime == -1) {
500
+ startTime = info.presentationTimeUs;
501
+ }
502
+ if (end < 0 || info.presentationTimeUs < end) {
503
+ info.offset = 0;
504
+ info.flags = extractor.getSampleFlags();
505
+ mediaMuxer.writeSampleData(muxerTrackIndex, buffer, info);
506
+ extractor.advance();
507
+ } else {
508
+ eof = true;
509
+ }
510
+ }
511
+ } else if (index == -1) {
512
+ eof = true;
513
+ }
514
+ if (eof) {
515
+ inputDone = true;
516
+ }
517
+ }
518
+
519
+ extractor.unselectTrack(trackIndex);
520
+ return startTime;
521
+ }
522
+ return -1;
523
+ }
524
+
525
+
526
+ private int selectTrack(MediaExtractor extractor, boolean audio) {
527
+ int numTracks = extractor.getTrackCount();
528
+ for (int i = 0; i < numTracks; i++) {
529
+ MediaFormat format = extractor.getTrackFormat(i);
530
+ String mime = format.getString(MediaFormat.KEY_MIME);
531
+ if (audio) {
532
+ if (mime.startsWith("audio/")) {
533
+ return i;
534
+ }
535
+ } else {
536
+ if (mime.startsWith("video/")) {
537
+ return i;
538
+ }
539
+ }
540
+ }
541
+ return MEDIATYPE_NOT_AUDIO_VIDEO;
542
+ }
543
+
544
+
545
+ /**
546
+ * Configures encoder and muxer state, and prepares the input Surface.
547
+ */
548
+ private void prepareEncoder(MediaFormat inputFormat) {
549
+ mBufferInfo = new MediaCodec.BufferInfo();
550
+
551
+ MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
552
+
553
+ // Set some properties. Failing to specify some of these can cause the MediaCodec
554
+ // configure() call to throw an unhelpful exception.
555
+ format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
556
+ MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
557
+ format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
558
+ format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
559
+ format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
560
+ if (VERBOSE) Log.d(TAG, "format: " + format);
561
+
562
+ // Create a MediaCodec encoder, and configure it with our format. Get a Surface
563
+ // we can use for input and wrap it with a class that handles the EGL work.
564
+ //
565
+ // If you want to have two EGL contexts -- one for display, one for recording --
566
+ // you will likely want to defer instantiation of CodecInputSurface until after the
567
+ // "display" EGL context is created, then modify the eglCreateContext call to
568
+ // take eglGetCurrentContext() as the share_context argument.
569
+ try {
570
+ mEncoder = MediaCodec.createEncoderByType(MIME_TYPE);
571
+ } catch (IOException e) {
572
+ e.printStackTrace();
573
+ }
574
+ mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
575
+ mInputSurface = new CodecInputSurface(mEncoder.createInputSurface());
576
+ mInputSurface.makeCurrent();
577
+ mEncoder.start();
578
+
579
+ try {
580
+ mDecoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME));
581
+ } catch (IOException e) {
582
+ e.printStackTrace();
583
+ }
584
+ mInputSurface.createRender();
585
+ mDecoder.configure(inputFormat, mInputSurface.getSurface(), null, 0);
586
+ mDecoder.start();
587
+
588
+ // Output filename. Ideally this would use Context.getFilesDir() rather than a
589
+ // hard-coded output directory.
590
+
591
+ // Create a MediaMuxer. We can't add the video track and start() the muxer here,
592
+ // because our MediaFormat doesn't have the Magic Goodies. These can only be
593
+ // obtained from the encoder after it has started processing data.
594
+ //
595
+ // We're not actually interested in multiplexing audio. We just want to convert
596
+ // the raw H.264 elementary stream we get from MediaCodec into a .mp4 file.
597
+
598
+
599
+ mTrackIndex = -1;
600
+ }
601
+
602
+ /**
603
+ * Releases encoder resources. May be called after partial / failed initialization.
604
+ */
605
+ private void releaseCoder() {
606
+ if (VERBOSE) Log.d(TAG, "releasing encoder objects");
607
+ if (mEncoder != null) {
608
+ mEncoder.stop();
609
+ mEncoder.release();
610
+ mEncoder = null;
611
+ }
612
+ if (mDecoder != null) {
613
+ mDecoder.stop();
614
+ mDecoder.release();
615
+ mDecoder = null;
616
+ }
617
+ if (mInputSurface != null) {
618
+ mInputSurface.release();
619
+ mInputSurface = null;
620
+ }
621
+ if (mMuxer != null) {
622
+ mMuxer.stop();
623
+ mMuxer.release();
624
+ mMuxer = null;
625
+ }
626
+ }
627
+
628
+
629
+ }
@@ -0,0 +1,59 @@
1
+ package com.reactnativecompressor.Video.videoslimmer;
2
+
3
+ import android.os.AsyncTask;
4
+
5
+ import com.reactnativecompressor.Video.videoslimmer.listner.SlimProgressListener;
6
+
7
+ public class VideoSlimTask extends AsyncTask<Object, Float, Boolean> {
8
+ private VideoSlimmer.ProgressListener mListener;
9
+
10
+
11
+ public VideoSlimTask(VideoSlimmer.ProgressListener listener) {
12
+ mListener = listener;
13
+
14
+ }
15
+
16
+ @Override
17
+ protected void onPreExecute() {
18
+ super.onPreExecute();
19
+ if (mListener != null) {
20
+ mListener.onStart();
21
+ }
22
+ }
23
+
24
+ @Override
25
+ protected Boolean doInBackground(Object... paths) {
26
+ return new VideoSlimEncoder().convertVideo((String)paths[0], (String)paths[1], (Integer)paths[2],(Integer)paths[3],(Integer)paths[4], new SlimProgressListener() {
27
+ @Override
28
+ public void onProgress(float percent) {
29
+ publishProgress(percent);
30
+ }
31
+ });
32
+ }
33
+
34
+ @Override
35
+ protected void onProgressUpdate(Float... percent) {
36
+ super.onProgressUpdate(percent);
37
+ if (mListener != null) {
38
+ mListener.onProgress(percent[0]);
39
+ }
40
+ }
41
+
42
+ @Override
43
+ protected void onPostExecute(Boolean result) {
44
+ super.onPostExecute(result);
45
+ if (mListener != null) {
46
+ if (result) {
47
+ mListener.onFinish(true);
48
+ } else {
49
+ mListener.onFinish(false);
50
+ }
51
+ }
52
+ }
53
+
54
+ @Override
55
+ protected void onCancelled() {
56
+ super.onCancelled();
57
+ mListener.onError("");
58
+ }
59
+ }