always mux videos when downloading (#1152)

* mux videos with and without audio

* move variable to inner scope

* rename argument to catch block
This commit is contained in:
Patrick Demers 2022-11-02 07:25:35 -05:00 committed by GitHub
parent 28ca5e6bbe
commit 4bec3e0922
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -224,9 +224,9 @@ public class DownloadRedditVideoService extends Service {
if (audioUrl != null) { if (audioUrl != null) {
Response<ResponseBody> audioResponse = downloadFile.downloadFile(audioUrl).execute(); Response<ResponseBody> audioResponse = downloadFile.downloadFile(audioUrl).execute();
String outputFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + ".mp4";
if (audioResponse.isSuccessful() && audioResponse.body() != null) { if (audioResponse.isSuccessful() && audioResponse.body() != null) {
String audioFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp3"; String audioFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp3";
String outputFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + ".mp4";
String savedAudioFilePath = writeResponseBodyToDisk(audioResponse.body(), audioFilePath); String savedAudioFilePath = writeResponseBodyToDisk(audioResponse.body(), audioFilePath);
if (savedAudioFilePath == null) { if (savedAudioFilePath == null) {
@ -256,11 +256,21 @@ public class DownloadRedditVideoService extends Service {
downloadFinished(null, ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE, randomNotificationIdOffset); downloadFinished(null, ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE, randomNotificationIdOffset);
} }
} else { } else {
updateNotification(R.string.downloading_reddit_video_muxing, -1,
randomNotificationIdOffset, null);
if (!muxVideoAndAudio(videoFilePath, null, outputFilePath)) {
downloadFinished(null, ERROR_MUX_FAILED, randomNotificationIdOffset);
return;
}
updateNotification(R.string.downloading_reddit_video_save_file_to_public_dir, -1, updateNotification(R.string.downloading_reddit_video_save_file_to_public_dir, -1,
randomNotificationIdOffset, null); randomNotificationIdOffset, null);
try { try {
Uri destinationFileUri = copyToDestination(videoFilePath, destinationFileUriString, destinationFileName, isDefaultDestination); Uri destinationFileUri = copyToDestination(outputFilePath, destinationFileUriString, destinationFileName, isDefaultDestination);
new File(videoFilePath).delete(); new File(videoFilePath).delete();
new File(outputFilePath).delete();
downloadFinished(destinationFileUri, NO_ERROR, randomNotificationIdOffset); downloadFinished(destinationFileUri, NO_ERROR, randomNotificationIdOffset);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -268,6 +278,7 @@ public class DownloadRedditVideoService extends Service {
} }
} }
} else { } else {
// do not remux video on <= Android N, just save video
updateNotification(R.string.downloading_reddit_video_save_file_to_public_dir, -1, updateNotification(R.string.downloading_reddit_video_save_file_to_public_dir, -1,
randomNotificationIdOffset, null); randomNotificationIdOffset, null);
try { try {
@ -344,66 +355,72 @@ public class DownloadRedditVideoService extends Service {
file.createNewFile(); file.createNewFile();
MediaExtractor videoExtractor = new MediaExtractor(); MediaExtractor videoExtractor = new MediaExtractor();
videoExtractor.setDataSource(videoFilePath); videoExtractor.setDataSource(videoFilePath);
MediaExtractor audioExtractor = new MediaExtractor();
audioExtractor.setDataSource(audioFilePath);
MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
videoExtractor.selectTrack(0); videoExtractor.selectTrack(0);
MediaFormat videoFormat = videoExtractor.getTrackFormat(0); MediaFormat videoFormat = videoExtractor.getTrackFormat(0);
int videoTrack = muxer.addTrack(videoFormat); int videoTrack = muxer.addTrack(videoFormat);
audioExtractor.selectTrack(0);
MediaFormat audioFormat = audioExtractor.getTrackFormat(0);
int audioTrack = muxer.addTrack(audioFormat);
boolean sawEOS = false; boolean sawEOS = false;
int offset = 100; int offset = 100;
int sampleSize = 4096 * 1024; int sampleSize = 4096 * 1024;
ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize); ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize);
ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize); ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize);
MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo(); MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo();
videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
// audio not present for all videos
MediaExtractor audioExtractor = new MediaExtractor();
MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo();
int audioTrack = -1;
if (audioFilePath != null) {
audioExtractor.setDataSource(audioFilePath);
audioExtractor.selectTrack(0);
MediaFormat audioFormat = audioExtractor.getTrackFormat(0);
audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
audioTrack = muxer.addTrack(audioFormat);
}
muxer.start(); muxer.start();
int muxedSize = 0;
while (!sawEOS) { while (!sawEOS) {
videoBufferInfo.offset = offset; videoBufferInfo.offset = offset;
videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset); videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset);
if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { if (videoBufferInfo.size < 0) {
sawEOS = true; sawEOS = true;
videoBufferInfo.size = 0; videoBufferInfo.size = 0;
} else { } else {
videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime(); videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime();
videoBufferInfo.flags = videoExtractor.getSampleFlags(); videoBufferInfo.flags = videoExtractor.getSampleFlags();
muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo); muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo);
muxedSize += videoTrack;
videoExtractor.advance(); videoExtractor.advance();
} }
} }
boolean sawEOS2 = false; if (audioFilePath != null) {
while (!sawEOS2) { boolean sawEOS2 = false;
audioBufferInfo.offset = offset; while (!sawEOS2) {
audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset); audioBufferInfo.offset = offset;
audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset);
if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { if (audioBufferInfo.size < 0) {
sawEOS2 = true; sawEOS2 = true;
audioBufferInfo.size = 0; audioBufferInfo.size = 0;
} else { } else {
audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime(); audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime();
audioBufferInfo.flags = audioExtractor.getSampleFlags(); audioBufferInfo.flags = audioExtractor.getSampleFlags();
muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo); muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo);
audioExtractor.advance(); audioExtractor.advance();
}
} }
} }
muxer.stop(); muxer.stop();
muxer.release(); muxer.release();
} catch (IllegalArgumentException | IllegalStateException ignore) { } catch (IllegalArgumentException | IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return false; return false;