fix pip
This commit is contained in:
parent
e19eb520b3
commit
7d20847840
3 changed files with 384 additions and 5 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
345
app/src/main/java/asgardius/page/s3manager/VideoPlayerPip.java
Normal file
345
app/src/main/java/asgardius/page/s3manager/VideoPlayerPip.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue