aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/main/AndroidManifest.xml1
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java40
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java510
3 files changed, 268 insertions, 283 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b80426e9..23da717d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -179,6 +179,7 @@
<service
android:name=".services.DownloadRedditVideoService"
android:enabled="true"
+ android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false" />
<activity
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java
index 14c544b4..07d166f3 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java
@@ -111,6 +111,7 @@ import ml.docilealligator.infinityforreddit.font.TitleFontStyle;
import ml.docilealligator.infinityforreddit.post.FetchPost;
import ml.docilealligator.infinityforreddit.post.Post;
import ml.docilealligator.infinityforreddit.services.DownloadMediaService;
+import ml.docilealligator.infinityforreddit.services.DownloadRedditVideoService;
import ml.docilealligator.infinityforreddit.utils.APIUtils;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
import ml.docilealligator.infinityforreddit.utils.Utils;
@@ -981,31 +982,6 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
private void download() {
isDownloading = false;
- /*Intent intent;
- if (videoType != VIDEO_TYPE_NORMAL) {
- intent = new Intent(this, DownloadMediaService.class);
- if (post.getPostType() == Post.GIF_TYPE) {
- intent.putExtra(DownloadMediaService.EXTRA_URL, post.getVideoUrl());
- intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_GIF);
- intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, post.getSubredditName()
- + "-" + post.getId() + ".gif");
- } else {
- intent.putExtra(DownloadMediaService.EXTRA_URL, videoDownloadUrl);
- intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_VIDEO);
- intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, videoFileName);
- }
-
- intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, subredditName);
- intent.putExtra(DownloadMediaService.EXTRA_IS_NSFW, isNSFW);
- } else {
- intent = new Intent(this, DownloadRedditVideoService.class);
- intent.putExtra(DownloadRedditVideoService.EXTRA_VIDEO_URL, videoDownloadUrl);
- intent.putExtra(DownloadRedditVideoService.EXTRA_POST_ID, id);
- intent.putExtra(DownloadRedditVideoService.EXTRA_SUBREDDIT, subredditName);
- intent.putExtra(DownloadRedditVideoService.EXTRA_IS_NSFW, isNSFW);
- }
- ContextCompat.startForegroundService(this, intent);*/
-
if (videoType != VIDEO_TYPE_NORMAL) {
PersistableBundle extras = new PersistableBundle();
if (post.getPostType() == Post.GIF_TYPE) {
@@ -1026,11 +1002,15 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
JobInfo jobInfo = DownloadMediaService.constructJobInfo(this, 5000000, extras);
((JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(jobInfo);
} else {
- /* intent = new Intent(this, DownloadRedditVideoService.class);
- intent.putExtra(DownloadRedditVideoService.EXTRA_VIDEO_URL, videoDownloadUrl);
- intent.putExtra(DownloadRedditVideoService.EXTRA_POST_ID, id);
- intent.putExtra(DownloadRedditVideoService.EXTRA_SUBREDDIT, subredditName);
- intent.putExtra(DownloadRedditVideoService.EXTRA_IS_NSFW, isNSFW);*/
+ PersistableBundle extras = new PersistableBundle();
+ extras.putString(DownloadRedditVideoService.EXTRA_VIDEO_URL, videoDownloadUrl);
+ extras.putString(DownloadRedditVideoService.EXTRA_POST_ID, id);
+ extras.putString(DownloadRedditVideoService.EXTRA_SUBREDDIT, subredditName);
+ extras.putInt(DownloadRedditVideoService.EXTRA_IS_NSFW, isNSFW ? 1 : 0);
+
+ //TODO: contentEstimatedBytes
+ JobInfo jobInfo = DownloadRedditVideoService.constructJobInfo(this, 5000000, extras);
+ ((JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(jobInfo);
}
Toast.makeText(this, R.string.download_started, Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java
index f9647da4..06728a4b 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java
@@ -4,9 +4,13 @@ import static android.os.Environment.getExternalStoragePublicDirectory;
import android.app.Notification;
import android.app.PendingIntent;
-import android.app.Service;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
+import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaCodec;
@@ -14,16 +18,11 @@ import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.media.MediaScannerConnection;
+import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Build;
-import android.os.Bundle;
import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
+import android.os.PersistableBundle;
import android.provider.MediaStore;
import androidx.annotation.NonNull;
@@ -41,6 +40,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Random;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
@@ -58,7 +58,7 @@ import okhttp3.ResponseBody;
import retrofit2.Response;
import retrofit2.Retrofit;
-public class DownloadRedditVideoService extends Service {
+public class DownloadRedditVideoService extends JobService {
public static final String EXTRA_VIDEO_URL = "EVU";
public static final String EXTRA_SUBREDDIT = "ES";
@@ -74,6 +74,8 @@ public class DownloadRedditVideoService extends Service {
private static final int ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE = 5;
private static final int ERROR_CANNOT_GET_DESTINATION_DIRECTORY = 6;
+ private static int JOB_ID = 30000;
+
@Inject
@Named("download_media")
Retrofit retrofit;
@@ -82,7 +84,8 @@ public class DownloadRedditVideoService extends Service {
SharedPreferences sharedPreferences;
@Inject
CustomThemeWrapper customThemeWrapper;
- private ServiceHandler serviceHandler;
+ @Inject
+ Executor executor;
private NotificationManagerCompat notificationManager;
private NotificationCompat.Builder builder;
private final String[] possibleAudioUrlSuffices = new String[]{"/DASH_AUDIO_128.mp4", "/DASH_audio.mp4", "/DASH_audio", "/audio.mp4", "/audio"};
@@ -90,22 +93,66 @@ public class DownloadRedditVideoService extends Service {
public DownloadRedditVideoService() {
}
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
+ public static JobInfo constructJobInfo(Context context, long contentEstimatedBytes, PersistableBundle extras) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ return new JobInfo.Builder(JOB_ID++, new ComponentName(context, DownloadRedditVideoService.class))
+ .setUserInitiated(true)
+ .setRequiredNetwork(new NetworkRequest.Builder().build())
+ .setEstimatedNetworkBytes(0, contentEstimatedBytes + 500)
+ .setExtras(extras)
+ .build();
+ } else {
+ return new JobInfo.Builder(JOB_ID++, new ComponentName(context, DownloadRedditVideoService.class))
+ .build();
}
- @Override
- public void handleMessage(Message msg) {
- Bundle intent = msg.getData();
- String videoUrl = intent.getString(EXTRA_VIDEO_URL);
+ }
+
+ @Override
+ public void onCreate() {
+ ((Infinity) getApplication()).getAppComponent().inject(this);
+ notificationManager = NotificationManagerCompat.from(this);
+ }
- String audioUrlPrefix = Build.VERSION.SDK_INT > Build.VERSION_CODES.N ? videoUrl.substring(0, videoUrl.lastIndexOf('/')) : null;
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ builder = new NotificationCompat.Builder(DownloadRedditVideoService.this, NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO);
- String subredditName = intent.getString(EXTRA_SUBREDDIT);
- String fileNameWithoutExtension = subredditName + "-" + intent.getString(EXTRA_POST_ID);
- boolean isNsfw = intent.getBoolean(EXTRA_IS_NSFW, false);
- int randomNotificationIdOffset = msg.arg1;
+ PersistableBundle intent = params.getExtras();
+ String subredditName = intent.getString(EXTRA_SUBREDDIT);
+ String fileNameWithoutExtension = subredditName + "-" + intent.getString(EXTRA_POST_ID);
+
+ NotificationChannelCompat serviceChannel =
+ new NotificationChannelCompat.Builder(
+ NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO,
+ NotificationManagerCompat.IMPORTANCE_LOW)
+ .setName(NotificationUtils.CHANNEL_DOWNLOAD_REDDIT_VIDEO)
+ .build();
+ notificationManager.createNotificationChannel(serviceChannel);
+
+ int randomNotificationIdOffset = new Random().nextInt(10000);
+ startForeground(
+ NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset,
+ createNotification(fileNameWithoutExtension + ".mp4")
+ );
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ setNotification(params,
+ NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset,
+ createNotification(fileNameWithoutExtension + ".mp4"),
+ JobService.JOB_END_NOTIFICATION_POLICY_DETACH);
+ } else {
+ notificationManager.notify(NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset,
+ createNotification(fileNameWithoutExtension + ".mp4"));
+ }
+
+ String videoUrl = intent.getString(EXTRA_VIDEO_URL);
+
+ String audioUrlPrefix = Build.VERSION.SDK_INT > Build.VERSION_CODES.N ? videoUrl.substring(0, videoUrl.lastIndexOf('/')) : null;
+
+ boolean isNsfw = intent.getInt(EXTRA_IS_NSFW, 0) == 1;
+
+ executor.execute(() -> {
final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() {
long time = 0;
@@ -141,6 +188,7 @@ public class DownloadRedditVideoService extends Service {
File externalCacheDirectory = getExternalCacheDir();
if (externalCacheDirectory != null) {
String destinationFileName = fileNameWithoutExtension + ".mp4";
+ String finalFileNameWithoutExtension = fileNameWithoutExtension;
try {
Response<ResponseBody> videoResponse = downloadFileRetrofit.downloadFile(videoUrl).execute();
@@ -201,11 +249,11 @@ public class DownloadRedditVideoService extends Service {
DocumentFile checkForDuplicates = dir.findFile(destinationFileName);
int num = 1;
while (checkForDuplicates != null) {
- fileNameWithoutExtension = fileNameWithoutExtension + " (" + num + ")";
- checkForDuplicates = dir.findFile(fileNameWithoutExtension + ".mp4");
+ finalFileNameWithoutExtension = finalFileNameWithoutExtension + " (" + num + ")";
+ checkForDuplicates = dir.findFile(finalFileNameWithoutExtension + ".mp4");
num++;
}
- picFile = dir.createFile("video/mp4", fileNameWithoutExtension + ".mp4");
+ picFile = dir.createFile("video/mp4", finalFileNameWithoutExtension + ".mp4");
if (picFile == null) {
downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY, randomNotificationIdOffset);
return;
@@ -216,7 +264,7 @@ public class DownloadRedditVideoService extends Service {
updateNotification(R.string.downloading_reddit_video_audio_track, 0,
randomNotificationIdOffset, null);
- String videoFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp4";
+ String videoFilePath = externalCacheDirectoryPath + finalFileNameWithoutExtension + "-cache.mp4";
String savedVideoFilePath = writeResponseBodyToDisk(videoResponse.body(), videoFilePath);
if (savedVideoFilePath == null) {
downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_SAVE, randomNotificationIdOffset);
@@ -225,9 +273,9 @@ public class DownloadRedditVideoService extends Service {
if (audioUrlPrefix != null) {
ResponseBody audioResponse = getAudioResponse(downloadFileRetrofit, audioUrlPrefix, 0);
- String outputFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + ".mp4";
+ String outputFilePath = externalCacheDirectoryPath + finalFileNameWithoutExtension + ".mp4";
if (audioResponse != null) {
- String audioFilePath = externalCacheDirectoryPath + fileNameWithoutExtension + "-cache.mp3";
+ String audioFilePath = externalCacheDirectoryPath + finalFileNameWithoutExtension + "-cache.mp3";
String savedAudioFilePath = writeResponseBodyToDisk(audioResponse, audioFilePath);
if (savedAudioFilePath == null) {
@@ -301,282 +349,238 @@ public class DownloadRedditVideoService extends Service {
} else {
downloadFinished(null, ERROR_CANNOT_GET_CACHE_DIRECTORY, randomNotificationIdOffset);
}
- }
+ });
- @Nullable
- private ResponseBody getAudioResponse(DownloadFile downloadFileRetrofit, @NonNull String audioUrlPrefix, int audioSuffixIndex) throws IOException {
- if (audioSuffixIndex >= possibleAudioUrlSuffices.length) {
- return null;
- }
+ return true;
+ }
- String audioUrl = audioUrlPrefix + possibleAudioUrlSuffices[audioSuffixIndex];
- Response<ResponseBody> audioResponse = downloadFileRetrofit.downloadFile(audioUrl).execute();
- ResponseBody responseBody = audioResponse.body();
- if (audioResponse.isSuccessful() && responseBody != null) {
- return responseBody;
- }
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ return false;
+ }
- return getAudioResponse(downloadFileRetrofit, audioUrlPrefix, audioSuffixIndex + 1);
+ @Nullable
+ private ResponseBody getAudioResponse(DownloadFile downloadFileRetrofit, @NonNull String audioUrlPrefix, int audioSuffixIndex) throws IOException {
+ if (audioSuffixIndex >= possibleAudioUrlSuffices.length) {
+ return null;
}
- private String writeResponseBodyToDisk(ResponseBody body, String filePath) {
- try {
- File file = new File(filePath);
+ String audioUrl = audioUrlPrefix + possibleAudioUrlSuffices[audioSuffixIndex];
+ Response<ResponseBody> audioResponse = downloadFileRetrofit.downloadFile(audioUrl).execute();
+ ResponseBody responseBody = audioResponse.body();
+ if (audioResponse.isSuccessful() && responseBody != null) {
+ return responseBody;
+ }
- InputStream inputStream = null;
- OutputStream outputStream = null;
+ return getAudioResponse(downloadFileRetrofit, audioUrlPrefix, audioSuffixIndex + 1);
+ }
- try {
- byte[] fileReader = new byte[4096];
+ private String writeResponseBodyToDisk(ResponseBody body, String filePath) {
+ try {
+ File file = new File(filePath);
- long fileSize = body.contentLength();
- long fileSizeDownloaded = 0;
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
- inputStream = body.byteStream();
- outputStream = new FileOutputStream(file);
+ try {
+ byte[] fileReader = new byte[4096];
- while (true) {
- int read = inputStream.read(fileReader);
+ long fileSize = body.contentLength();
+ long fileSizeDownloaded = 0;
- if (read == -1) {
- break;
- }
+ inputStream = body.byteStream();
+ outputStream = new FileOutputStream(file);
- outputStream.write(fileReader, 0, read);
+ while (true) {
+ int read = inputStream.read(fileReader);
- fileSizeDownloaded += read;
+ if (read == -1) {
+ break;
}
- outputStream.flush();
-
- return file.getPath();
- } catch (IOException e) {
- return null;
- } finally {
- if (inputStream != null) {
- inputStream.close();
- }
+ outputStream.write(fileReader, 0, read);
- if (outputStream != null) {
- outputStream.close();
- }
+ fileSizeDownloaded += read;
}
+
+ outputStream.flush();
+
+ return file.getPath();
} catch (IOException e) {
return null;
+ } finally {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+
+ if (outputStream != null) {
+ outputStream.close();
+ }
}
+ } catch (IOException e) {
+ return null;
}
+ }
- private boolean muxVideoAndAudio(String videoFilePath, String audioFilePath, String outputFilePath) {
- try {
- File file = new File(outputFilePath);
- file.createNewFile();
- MediaExtractor videoExtractor = new MediaExtractor();
- videoExtractor.setDataSource(videoFilePath);
- MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
-
- videoExtractor.selectTrack(0);
- MediaFormat videoFormat = videoExtractor.getTrackFormat(0);
- int videoTrack = muxer.addTrack(videoFormat);
-
- boolean sawEOS = false;
- int offset = 100;
- int sampleSize = 4096 * 1024;
- ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize);
- ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize);
- MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
-
- videoExtractor.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);
- }
+ private boolean muxVideoAndAudio(String videoFilePath, String audioFilePath, String outputFilePath) {
+ try {
+ File file = new File(outputFilePath);
+ file.createNewFile();
+ MediaExtractor videoExtractor = new MediaExtractor();
+ videoExtractor.setDataSource(videoFilePath);
+ MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+
+ videoExtractor.selectTrack(0);
+ MediaFormat videoFormat = videoExtractor.getTrackFormat(0);
+ int videoTrack = muxer.addTrack(videoFormat);
+
+ boolean sawEOS = false;
+ int offset = 100;
+ int sampleSize = 4096 * 1024;
+ ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize);
+ ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize);
+ MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
+
+ videoExtractor.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();
- while (!sawEOS) {
- videoBufferInfo.offset = offset;
- videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset);
+ while (!sawEOS) {
+ videoBufferInfo.offset = offset;
+ videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset);
- if (videoBufferInfo.size < 0) {
- sawEOS = true;
- videoBufferInfo.size = 0;
- } else {
- videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime();
- videoBufferInfo.flags = videoExtractor.getSampleFlags();
- muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo);
- videoExtractor.advance();
- }
+ if (videoBufferInfo.size < 0) {
+ sawEOS = true;
+ videoBufferInfo.size = 0;
+ } else {
+ videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime();
+ videoBufferInfo.flags = videoExtractor.getSampleFlags();
+ muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo);
+ videoExtractor.advance();
}
+ }
- if (audioFilePath != null) {
- boolean sawEOS2 = false;
- while (!sawEOS2) {
- audioBufferInfo.offset = offset;
- audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset);
+ if (audioFilePath != null) {
+ boolean sawEOS2 = false;
+ while (!sawEOS2) {
+ audioBufferInfo.offset = offset;
+ audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset);
- if (audioBufferInfo.size < 0) {
- sawEOS2 = true;
- audioBufferInfo.size = 0;
- } else {
- audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime();
- audioBufferInfo.flags = audioExtractor.getSampleFlags();
- muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo);
- audioExtractor.advance();
- }
+ if (audioBufferInfo.size < 0) {
+ sawEOS2 = true;
+ audioBufferInfo.size = 0;
+ } else {
+ audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime();
+ audioBufferInfo.flags = audioExtractor.getSampleFlags();
+ muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo);
+ audioExtractor.advance();
}
}
-
- muxer.stop();
- muxer.release();
- } catch (IllegalArgumentException | IllegalStateException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- return false;
}
- return true;
+ muxer.stop();
+ muxer.release();
+ } catch (IllegalArgumentException | IllegalStateException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
}
- private Uri copyToDestination(String srcPath, String destinationFileUriString, String destinationFileName,
- boolean isDefaultDestination) throws IOException {
- ContentResolver contentResolver = getContentResolver();
- if (isDefaultDestination) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- InputStream in = new FileInputStream(srcPath);
- OutputStream out = new FileOutputStream(destinationFileUriString);
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
-
- new File(srcPath).delete();
- } else {
- ContentValues contentValues = new ContentValues();
- contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, destinationFileName);
- contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
- contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFileUriString);
- contentValues.put(MediaStore.Video.Media.IS_PENDING, 1);
+ return true;
+ }
- OutputStream stream = null;
- Uri uri = null;
+ private Uri copyToDestination(String srcPath, String destinationFileUriString, String destinationFileName,
+ boolean isDefaultDestination) throws IOException {
+ ContentResolver contentResolver = getContentResolver();
+ if (isDefaultDestination) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ InputStream in = new FileInputStream(srcPath);
+ OutputStream out = new FileOutputStream(destinationFileUriString);
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
- try {
- final Uri contentUri = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
- uri = contentResolver.insert(contentUri, contentValues);
+ new File(srcPath).delete();
+ } else {
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, destinationFileName);
+ contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
+ contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFileUriString);
+ contentValues.put(MediaStore.Video.Media.IS_PENDING, 1);
- if (uri == null) {
- throw new IOException("Failed to create new MediaStore record.");
- }
+ OutputStream stream = null;
+ Uri uri = null;
- stream = contentResolver.openOutputStream(uri);
+ try {
+ final Uri contentUri = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
+ uri = contentResolver.insert(contentUri, contentValues);
- if (stream == null) {
- throw new IOException("Failed to get output stream.");
- }
+ if (uri == null) {
+ throw new IOException("Failed to create new MediaStore record.");
+ }
- InputStream in = new FileInputStream(srcPath);
+ stream = contentResolver.openOutputStream(uri);
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- stream.write(buf, 0, len);
- }
+ if (stream == null) {
+ throw new IOException("Failed to get output stream.");
+ }
- contentValues.clear();
- contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
- contentResolver.update(uri, contentValues, null, null);
- return uri;
- } catch (IOException e) {
- if (uri != null) {
- // Don't leave an orphan entry in the MediaStore
- contentResolver.delete(uri, null, null);
- }
+ InputStream in = new FileInputStream(srcPath);
- throw e;
- } finally {
- if (stream != null) {
- stream.close();
- }
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ stream.write(buf, 0, len);
}
- }
- } else {
- OutputStream stream = contentResolver.openOutputStream(Uri.parse(destinationFileUriString));
- if (stream == null) {
- throw new IOException("Failed to get output stream.");
- }
- InputStream in = new FileInputStream(srcPath);
+ contentValues.clear();
+ contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
+ contentResolver.update(uri, contentValues, null, null);
+ return uri;
+ } catch (IOException e) {
+ if (uri != null) {
+ // Don't leave an orphan entry in the MediaStore
+ contentResolver.delete(uri, null, null);
+ }
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- stream.write(buf, 0, len);
+ throw e;
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
}
}
+ } else {
+ OutputStream stream = contentResolver.openOutputStream(Uri.parse(destinationFileUriString));
+ if (stream == null) {
+ throw new IOException("Failed to get output stream.");
+ }
- return Uri.parse(destinationFileUriString);
- }
- }
-
- @Override
- public void onCreate() {
- ((Infinity) getApplication()).getAppComponent().inject(this);
- notificationManager = NotificationManagerCompat.from(this);
- // Start up the thread running the service. Note that we create a
- // separate thread because the service normally runs in the process's
- // main thread, which we don't want to block. We also make it
- // background priority so CPU-intensive work doesn't disrupt our UI.
- HandlerThread thread = new HandlerThread("ServiceStartArguments",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
-
- // Get the HandlerThread's Looper and use it for our Handler
- serviceHandler = new ServiceHandler(thread.getLooper());
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- builder = new NotificationCompat.Builder(DownloadRedditVideoService.this, NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO);
-
- String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT);
- String fileNameWithoutExtension = subredditName + "-" + intent.getStringExtra(EXTRA_POST_ID);
-
- NotificationChannelCompat serviceChannel =
- new NotificationChannelCompat.Builder(
- NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO,
- NotificationManagerCompat.IMPORTANCE_LOW)
- .setName(NotificationUtils.CHANNEL_DOWNLOAD_REDDIT_VIDEO)
- .build();
- notificationManager.createNotificationChannel(serviceChannel);
-
- int randomNotificationIdOffset = new Random().nextInt(10000);
- startForeground(
- NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID + randomNotificationIdOffset,
- createNotification(fileNameWithoutExtension + ".mp4")
- );
+ InputStream in = new FileInputStream(srcPath);
- Message msg = serviceHandler.obtainMessage();
- Bundle bundle = intent.getExtras();
- msg.setData(bundle);
- msg.arg1 = randomNotificationIdOffset;
- serviceHandler.sendMessage(msg);
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ stream.write(buf, 0, len);
+ }
+ }
- return START_NOT_STICKY;
+ return Uri.parse(destinationFileUriString);
}
private void downloadFinished(Uri destinationFileUri, int errorCode, int randomNotificationIdOffset) {