This commit is contained in:
Page Asgardius 2022-10-11 08:08:15 -07:00
parent e19eb520b3
commit 7d20847840
3 changed files with 384 additions and 5 deletions

View file

@ -91,6 +91,14 @@
android:supportsPictureInPicture="true"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout|uiMode|keyboardHidden"
android:exported="false"
android:launchMode="singleTask"
android:theme="@style/Theme.AsgardiusS3Manager.NoActionBar" />
<activity
android:name=".VideoPlayerPip"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|screenLayout|uiMode|keyboardHidden"
android:exported="false"
android:launchMode="singleInstance"
android:theme="@style/Theme.AsgardiusS3Manager.NoActionBar" />
<activity

View file

@ -5,8 +5,13 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.AppOpsManager;
import android.app.PictureInPictureParams;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
@ -51,6 +56,7 @@ public class ObjectSelect extends AppCompatActivity {
AmazonS3 s3client;
ProgressBar simpleProgressBar;
int videocache, videotime, buffersize;
AppOpsManager appOpsManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -66,6 +72,7 @@ public class ObjectSelect extends AppCompatActivity {
videocache = getIntent().getIntExtra("videocache", 40);
videotime = getIntent().getIntExtra("videotime", 1);
buffersize = getIntent().getIntExtra("buffersize", 2000);
appOpsManager = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
setContentView(R.layout.activity_object_select);
getSupportActionBar().setTitle(bucket+"/"+prefix);
region = Region.getRegion(location);
@ -406,11 +413,30 @@ public class ObjectSelect extends AppCompatActivity {
private void videoPlayer(String url) {
Intent intent = new Intent(this, VideoPlayer.class);
intent.putExtra("video_url", url);
intent.putExtra("videocache", videocache);
intent.putExtra("buffersize", buffersize);
startActivity(intent);
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& this.getPackageManager()
.hasSystemFeature(
PackageManager.FEATURE_PICTURE_IN_PICTURE) && appOpsManager.checkOpNoThrow(
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
this.getPackageManager().getApplicationInfo(this.getPackageName(),
PackageManager.GET_META_DATA).uid, this.getPackageName())
== AppOpsManager.MODE_ALLOWED) {
Intent intent = new Intent(this, VideoPlayerPip.class);
intent.putExtra("video_url", url);
intent.putExtra("videocache", videocache);
intent.putExtra("buffersize", buffersize);
startActivity(intent);
} else {
Intent intent = new Intent(this, VideoPlayer.class);
intent.putExtra("video_url", url);
intent.putExtra("videocache", videocache);
intent.putExtra("buffersize", buffersize);
startActivity(intent);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
private void textViewer(String url) {

View file

@ -0,0 +1,345 @@
package asgardius.page.s3manager;
import android.app.AppOpsManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.support.v4.media.session.MediaSessionCompat;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import java.io.File;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
public class VideoPlayerPip extends AppCompatActivity {
// creating a variable for exoplayerview.
protected StyledPlayerView playerView;
private WifiManager.WifiLock mWifiLock;
private PowerManager.WakeLock mWakeLock;
private PowerManager powerManager;
private long maxCacheSize;
LeastRecentlyUsedCacheEvictor evictor;
StandaloneDatabaseProvider standaloneDatabaseProvider;
SimpleCache simpleCache;
int videocache, buffersize;
ProgressiveMediaSource mediaSource;
DefaultLoadControl loadControl;
DefaultRenderersFactory renderersFactory;
ExoPlayer player;
long videoPosition;
MediaSessionCompat mediaSession;
MediaSessionConnector mediaSessionConnector;
StyledPlayerView.ControllerVisibilityListener control;
AppOpsManager appOpsManager;
private PlayerNotificationManager playerNotificationManager;
private int notificationId = 1234;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_player);
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.O){
NotificationChannel channel= new NotificationChannel("playback","Video Playback", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager =getSystemService(NotificationManager.class);
channel.setSound(null, null);
manager.createNotificationChannel(channel);
}
appOpsManager = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
mediaSession = new MediaSessionCompat(this, getPackageName());
mediaSessionConnector = new MediaSessionConnector(mediaSession);
hideSystemBars();
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.AUDIO_CONTENT_TYPE_MOVIE)
.build();
// create Wifi and wake locks
mWifiLock = ((WifiManager) this.getApplicationContext().getSystemService(Context.WIFI_SERVICE)).createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "S3Manager:wifi_lock");
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "S3Manager:wake_lock");
//Get media url
String videoURL = getIntent().getStringExtra("video_url");
videocache = getIntent().getIntExtra("videocache", 40);
buffersize = getIntent().getIntExtra("buffersize", 2000);
loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(2000, buffersize, 1500, 2000).build();
@DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode = DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER;
renderersFactory = new DefaultRenderersFactory(this) .setExtensionRendererMode(extensionRendererMode);
standaloneDatabaseProvider = new StandaloneDatabaseProvider(this);
maxCacheSize = (long)videocache * 1024 * 1024;
playerView = findViewById(R.id.player_view);
// creating a variable for exoplayer
player = new ExoPlayer.Builder(this).setLoadControl(loadControl).build();
player.setAudioAttributes(audioAttributes, true);
mediaSessionConnector.setPlayer(player);
mediaSession.setActive(true);
evictor = new LeastRecentlyUsedCacheEvictor(maxCacheSize);
simpleCache = new SimpleCache(
new File(this.getCacheDir(), "media"),
evictor,
standaloneDatabaseProvider);
mediaSource = new ProgressiveMediaSource.Factory(
new CacheDataSource.Factory()
.setCache(simpleCache)
.setUpstreamDataSourceFactory(new DefaultHttpDataSource.Factory()
.setUserAgent("ExoplayerDemo"))
.setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
).createMediaSource(MediaItem.fromUri(Uri.parse(videoURL)));
playerView.setPlayer(player);
control = new StyledPlayerView.ControllerVisibilityListener() {
@Override
public void onVisibilityChanged(int visibility) {
if (playerView.isControllerFullyVisible()) {
showSystemBars();
} else {
hideSystemBars();
}
}
};
playerView.setControllerVisibilityListener(control);
//MediaItem mediaItem = MediaItem.fromUri(videoURL);
// Set the media item to be played.
//player.setMediaItem(mediaItem);
// Prepare the player.
player.setPlayWhenReady(true);
playerNotificationManager = new PlayerNotificationManager.Builder(this, notificationId, "playback").build();
playerNotificationManager.setMediaSessionToken(mediaSession.getSessionToken());
playerNotificationManager.setPlayer(player);
player.setMediaSource(mediaSource);
player.prepare();
// Start the playback.
player.play();
player.addListener(new Player.Listener() {
@Override
public void onPlayerError(PlaybackException error) {
Throwable cause = error.getCause();
if (cause instanceof HttpDataSource.HttpDataSourceException) {
// An HTTP error occurred.
//System.out.println("Playback error F");
Toast.makeText(getApplicationContext(), getResources().getString(R.string.media_conn_fail), Toast.LENGTH_SHORT).show();
} else {
// An HTTP error occurred.
//System.out.println("Playback error F");
Toast.makeText(getApplicationContext(), getResources().getString(R.string.media_wrong_type), Toast.LENGTH_SHORT).show();
}
player.release();
finish();
}
});
player.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(@Player.State int state) {
if (state == 3) {
// Active playback.
//Acquiring WakeLock and WifiLock if not held
if (!mWifiLock.isHeld()) {
mWifiLock.acquire();
//System.out.println("WifiLock acquired");
}
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
//System.out.println("WakeLock acquired");
}
} else if (state == 2) {
// Buffering.
//Acquiring WakeLock and WifiLock if not held
if (!mWifiLock.isHeld()) {
mWifiLock.acquire();
//System.out.println("WifiLock acquired");
}
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
//System.out.println("WakeLock acquired");
}
} else {
//Player inactive
//Releasing WifiLock and WakeLock if held
if (mWifiLock.isHeld()) {
mWifiLock.release();
//System.out.println("WifiLock released");
}
if (mWakeLock.isHeld()) {
mWakeLock.release();
//System.out.println("WakeLock released");
}
// Not playing because playback is paused, ended, suppressed, or the player
// is buffering, stopped or failed. Check player.getPlayWhenReady,
// player.getPlaybackState, player.getPlaybackSuppressionReason and
// player.getPlaybackError for details.
}
}
});
}
private void hideSystemBars() {
// Set the IMMERSIVE flag.
// Set the content to appear under the system bars so that the content
// doesn't resize when the system bars hide and show.
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE);
}
private void showSystemBars() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
protected void enterPIPMode() {
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& this.getPackageManager()
.hasSystemFeature(
PackageManager.FEATURE_PICTURE_IN_PICTURE) && appOpsManager.checkOpNoThrow(
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
this.getPackageManager().getApplicationInfo(this.getPackageName(),
PackageManager.GET_META_DATA).uid, this.getPackageName())
== AppOpsManager.MODE_ALLOWED) {
videoPosition = player.getCurrentPosition();
playerView.setUseController(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
PictureInPictureParams params = new PictureInPictureParams.Builder().build();
this.enterPictureInPictureMode(params);
}else {
this.enterPictureInPictureMode();
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
mediaSessionConnector.setPlayer(null);
mediaSession.setActive(false);
playerNotificationManager.setPlayer(null);
player.release();
playerView.setPlayer(null);
simpleCache.release();
super.onDestroy();
}
public void onResume(){
super.onResume();
// put your code here...
if (!playerView.getUseController()) {
playerView.setUseController(true);
}
}
public void onUserLeaveHint() {
super.onUserLeaveHint();
enterPIPMode();
}
public void onBackPressed() {
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
&& this.getPackageManager()
.hasSystemFeature(
PackageManager.FEATURE_PICTURE_IN_PICTURE) && appOpsManager.checkOpNoThrow(
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
this.getPackageManager().getApplicationInfo(this.getPackageName(),
PackageManager.GET_META_DATA).uid, this.getPackageName())
== AppOpsManager.MODE_ALLOWED) {
enterPIPMode();
} else {
super.onBackPressed();
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
super.onBackPressed();
}
}
private class DescriptionAdapter implements
PlayerNotificationManager.MediaDescriptionAdapter {
@Override
public String getCurrentContentTitle(Player player) {
int window = player.getCurrentMediaItemIndex();
return getTitle().toString();
}
@Nullable
@Override
public String getCurrentContentText(Player player) {
int window = player.getCurrentMediaItemIndex();
return getCurrentContentText(player);
}
@Nullable
@Override
public Bitmap getCurrentLargeIcon(Player player,
PlayerNotificationManager.BitmapCallback callback) {
int window = player.getCurrentMediaItemIndex();
Bitmap largeIcon = getCurrentLargeIcon(player, callback);
/*if (largeIcon == null && getLargeIconUri(window) != null) {
// load bitmap async
loadBitmap(getLargeIconUri(window), callback);
return getPlaceholderBitmap();
}*/
return largeIcon;
}
@Nullable
@Override
public PendingIntent createCurrentContentIntent(Player player) {
int window = player.getCurrentMediaItemIndex();
//return createPendingIntent(window);
return null;
}
}
}