我正在尝试在自定义textureview上播放一些rtsp视频。视频是第一次播放但是当我进入第二个活动时播放相同的视频(没有重新实例化,同一个会话但具有不同的纹理视图)那里正在播放并回到第一个活动,我在onResume textureview中再次设置sureface仍然显示它第一次离开的内容。有趣的事实就像视频仍在播放,只是它在纹理视图中不可见,如果我在显示之前转到第二个屏幕。我尝试释放surfacetexture而不释放,尝试释放我在第一个活动中持有引用以供将来使用的表面,而不是任何一个似乎都工作。可以是什么可能的原因?
在onResume我正在检查应用程序是否从应用程序抽屉或全屏活动回来。通过单击主页按钮使应用程序转到后台并从应用程序抽屉视频回到应用程序正在播放。只有当从完整回来时屏幕它不能正常工作。
StreamingActivity.java
package com.wiznsystems.android.activities;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.myeglu.android.R;
import com.myeglu.zoomview.ZoomTextureView;
import com.wiznsystems.android.App;
import com.wiznsystems.android.data.objects.FFMPEG;
import com.wiznsystems.android.utils.Constants;
import com.wiznsystems.android.utils.Events;
import com.wiznsystems.android.utils.FFMPEGPlayer;
import java.io.File;
import de.greenrobot.event.EventBus;
import hugo.weaving.DebugLog;
import timber.log.Timber;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*/
@SuppressWarnings("JniMissingFunction")
public class StreamingActivity extends Fragment implements TextureView.SurfaceTextureListener{
private static boolean loadedLibraries;
private boolean comingFromAppDrawer;
private boolean isComingFromFullScreen;
boolean anotherVideo=false;
boolean shouldTextureUpdate=false;
Surface surface;
public StreamingActivity(){
}
public static ZoomTextureView surfaceView;
private ProgressBar progressBar;
public static boolean isPlaying;
private int isInitialized;
public static int isFullScreenDisplayed=0;
private String url;
public boolean isFirstTime;
private FFMPEG ffmpeg;
private FrameLayout frameLayout;
private final String TAG=StreamingActivity.class.getSimpleName();
int w=0,h=0;
private boolean isFirstTimeForFullscreen=true;
private Button fullScreenButton;
FFMPEGPlayer ffmpegPlayer;
String buttonText="";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
url=getArguments().getString("url");
Log.d("ANURAN",url);
//getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
ffmpegPlayer=App.getFFMPEG();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.activity_streaming,null,false);
surfaceView = (ZoomTextureView) view.findViewById(R.id.textureView);
frameLayout=(FrameLayout)view.findViewById(R.id.streaming_framelayout);
progressBar = ((ProgressBar)view.findViewById(R.id.progressBar));
fullScreenButton=(Button)view.findViewById(R.id.fullScreenButton);
fullScreenButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
isFullScreenDisplayed = 1;
isComingFromFullScreen = true;
shouldTextureUpdate=true;
if (isFirstTimeForFullscreen) {
//ffmpegPlayer.libSetSurface(null);
isFirstTimeForFullscreen = false;
}
//surfaceView.getSurfaceTexture().release();
//surface.release();
progressBar.setVisibility(View.INVISIBLE);
goFullScreen();
} catch (Exception throwable) {
throwable.printStackTrace();
}
}
});
progressBar.setVisibility(View.VISIBLE);
Log.d("ANURAN","onCreateView called");
surfaceView.setSurfaceTextureListener(this);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//Log.d(TAG,url);
}
@DebugLog
private void postInit() {
Events.PlayButtonBGChanger playButtonBGChanger=new Events.PlayButtonBGChanger();
if (isInitialized==0) {
playButtonBGChanger.setShouldChange(true);
initPlay();
progressBar.setVisibility(View.GONE);
} else if(isInitialized==-999){
playButtonBGChanger.setShouldChange(false);
progressBar.setVisibility(View.INVISIBLE);
Snackbar.make(frameLayout,"Please make sure you have stopped other playing videos before playing this one.",Snackbar.LENGTH_LONG).show();
}
else {
playButtonBGChanger.setShouldChange(false);
Snackbar.make(frameLayout,"Something went wrong while live streaming.Please try again later.",Snackbar.LENGTH_LONG).show();
}
EventBus.getDefault().post(playButtonBGChanger);
}
private void initPlay() {
try {
int[] res = ffmpegPlayer.libGetVideoRes();
Log.d("ANURAN", "res width " + res[0] + ": height " + res[1]);
if (res[0] <= 0) {
res[0] = 480;
}
if (res[1] <= 0) {
res[1] = 320;
}
int[] screenRes = getScreenRes();
int width, height;
float widthScaledRatio = screenRes[0] * 1.0f / res[0];
float heightScaledRatio = screenRes[1] * 1.0f / res[1];
if (widthScaledRatio > heightScaledRatio) {
//use heightScaledRatio
width = (int) (res[0] * heightScaledRatio);
height = screenRes[1];
} else {
//use widthScaledRatio
width = screenRes[0];
height = (int) (res[1] * widthScaledRatio);
}
Log.d(TAG, "width " + width + ",height:" + height);
w=width;
h=height;
updateSurfaceView(width, height);
try{
ffmpegPlayer.libSetup(width,height);
if(this.surface == null){
Log.d("ANURAN","surface is null");
}
if(anotherVideo)
ffmpegPlayer.libSetSurface(null);
ffmpegPlayer.libSetSurface(surface);
Log.d("ANURAN","libsetsurface set initPlay()");
}catch (Exception throwable){
Toast.makeText(getActivity(),"Something went wrong while live streaming.Try again",Toast.LENGTH_SHORT).show();
}
playMedia();
}catch (Exception throwable){
throwable.printStackTrace();
}
}
public FFMPEGPlayer getFFMPEGPlayer(){
return this.ffmpegPlayer;
}
private void playMedia() {
if(progressBar.getVisibility()==View.VISIBLE){
progressBar.setVisibility(View.GONE);
}
try{
ffmpegPlayer.libPlay();
}catch (Exception throwable){
Toast.makeText(getActivity(),"Something went wrong while live streaming.Try again",Toast.LENGTH_SHORT).show();
}
isPlaying = true;
CamerasActivity.isPlaying=true;
}
@DebugLog
private void updateSurfaceView(int pWidth, int pHeight) {
//update surfaceview dimension, this will cause the native window to change
Log.d("ANURAN UPDATE SURFACE", "width " + pWidth + ",height:" + pHeight);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) surfaceView.getLayoutParams();
params.width = pWidth;
params.height = pHeight;
surfaceView.setLayoutParams(params);
surfaceView.requestLayout();
}
@DebugLog
@SuppressLint("NewApi")
private int[] getScreenRes() {
int[] res = new int[2];
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
res[0] = size.x;
res[1] = size.y;
return res;
}
public void stopPlaying() {
isPlaying = false;
try{
ffmpegPlayer.libStop();
// ffmpegPlayer.libSetSurface(null);
// surfaceView.getSurfaceTexture().release();
// surfaceView.getSurfaceTexture().detachFromGLContext();
}catch (Exception throwable){
}
}
@Override
public void onStop() {
// Toast.makeText(getActivity(),"onStop called",Toast.LENGTH_SHORT).show();
// stopPlaying();
comingFromAppDrawer=true;
// if(surfaceView.getSurfaceTexture() !=null){
// surfaceView.getSurfaceTexture().release();
//
// }
// if(surface !=null){
// surface.release();
// surface=null;
// }
// if(isFullScreenDisplayed==0){
// stopPlaying();
// }
Log.d("ANURAN onStop",surface.isValid()+"");
super.onStop();
}
@Override
public void onPause() {
// Toast.makeText(getActivity(),"onStop called",Toast.LENGTH_SHORT).show();
// stopPlaying();
isComingFromFullScreen=true;
super.onPause();
}
@Override
public void onResume() {
super.onResume();
if(isComingFromFullScreen){
progressBar.setVisibility(View.INVISIBLE);
if(surface !=null){
ffmpegPlayer.libSetSurface(null);
Log.d("ANURAN onResume","value of surface "+surface.isValid());
ffmpegPlayer.libSetSurface(surface);
}
}
else if(comingFromAppDrawer){
//stopPlaying();
progressBar.setVisibility(View.INVISIBLE);
if(surface !=null){
ffmpegPlayer.libSetSurface(null);
//ffmpegPlayer.libSetup(w,h);
ffmpegPlayer.libSetSurface(surface);
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
stopPlaying();
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
if(this.surface !=null) {
this.surface.release();
this.surface=null;
}
this.surface=new Surface(surface);
Log.d("ANURAN","surfacetexture available streaming activity");
new PlayVideo().execute();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
Log.d("ANURAN","surfacetexturesize changed streaming activity");
try{
w=width;
h=height;
this.surface.release();
this.surface=null;
this.surface=new Surface(surface);
if(isComingFromFullScreen){
//surfaceView.getHolder().getSurface().release();
updateSurfaceView(width, height);
ffmpegPlayer.libSetup(width,height);
ffmpegPlayer.libSetSurface(this.surface);
}
}catch (Exception throwable){
Toast.makeText(getActivity(),"Something went wrong while live streaming.Try again",Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.d("ANURAN","surfacetexture destroyed streaming activity");
// surfaceView.getSurfaceTexture().release();
// if(this.surface !=null){
// this.surface.release();
// this.surface=null;
// }
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
Log.d("ANURAN","surfacetexture updated streaming activity");
if(this.surface !=null){
this.surface.release();
this.surface=null;
this.surface=new Surface(surface);
}else{
this.surface=new Surface(surface);
}
}
public class PlayVideo extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... voids) {
try{
isInitialized=ffmpegPlayer.libInit(url);
}catch (Exception e){
e.printStackTrace();
Snackbar.make(frameLayout,"Exception Occured",Snackbar.LENGTH_SHORT).show();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
isFirstTime=false;
postInit();
this.cancel(true);
}
}
public void onEvent(FFMPEG ffmpeg){
url = ffmpeg.getUrl();
progressBar.setVisibility(View.VISIBLE);
//stopPlaying();
anotherVideo=true;
new PlayVideo().execute();
}
public void onEvent(Events.UpdateUrl newurl){
url=newurl.getUrl();
}
public void onEvent(Events.StopPlayback event){
stopPlaying();
}
public void onEvent(Events.NotifyPlayer notifyPlayer){
Snackbar.make(frameLayout,"Please stop any running video before playing another one",Toast.LENGTH_SHORT).show();
}
private void goFullScreen(){
Intent intent=new Intent(getContext(),FullScreenActivity.class);
Bundle bundle=new Bundle();
bundle.putString("url",url);
intent.putExtras(bundle);
getActivity().startActivity(intent);
}
}
FullScreenActivity.java
package com.wiznsystems.android.activities;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.myeglu.android.R;
import com.myeglu.zoomview.AngleView;
import com.myeglu.zoomview.MatrixChangeListener;
import com.myeglu.zoomview.ZoomTextureView;
import com.wiznsystems.android.App;
import com.wiznsystems.android.data.objects.FFMPEG;
import com.wiznsystems.android.utils.FFMPEGPlayer;
import uk.copywitchshame.senab.photoview.gestures.PhotoViewAttacher;
import hugo.weaving.DebugLog;
/**
* Created by anuran on 9/3/18.
*/
@SuppressWarnings("JniMissingFunction")
public class FullScreenActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener, PhotoViewAttacher.OnMatrixChangedListener {
private ZoomTextureView surfaceView;
public static AngleView angleView;
private ProgressBar progressBar;
private PhotoViewAttacher photoViewAttacher;
public static boolean isPlaying;
private boolean isInitialized;
private String url;
private FrameLayout frameLayout;
Surface surface;
private final String TAG=StreamingActivity.class.getSimpleName();
public int backCounter=0;
FFMPEGPlayer ffmpegPlayer;
boolean fromADorSL=false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_fullscreen);
surfaceView = (ZoomTextureView) findViewById(R.id.textureView);
angleView=(AngleView)findViewById(R.id.render_angle_view);
surfaceView.setSurfaceTextureListener(this);
frameLayout=(FrameLayout)findViewById(R.id.streaming_framelayout);
progressBar = ((ProgressBar)findViewById(R.id.progressBar));
progressBar.setVisibility(View.VISIBLE);
url=getIntent().getExtras().getString("url");
//new PlayVideo().execute();
ffmpegPlayer= App.getFFMPEG();
Log.d("ANURAN","fullscreen onCreate");
}
// @DebugLog
// private void postInit() {
// if (isInitialized) {
// initPlay();
// progressBar.setVisibility(View.GONE);
// } else {
// finish();
// }
// }
// private void initPlay() {
//
// try{
// int[] res = FFMPEGPlayer.libGetVideoRes();
// Log.d("ANURAN", "res width " + res[0] + ": height " + res[1]);
// if (res[0] <= 0) {
// res[0] = 480;
// }
// if (res[1] <= 0) {
// res[1] = 320;
// }
// int[] screenRes = getScreenRes();
// int width, height;
// float widthScaledRatio = screenRes[0] * 1.0f / res[0];
// float heightScaledRatio = screenRes[1] * 1.0f / res[1];
// if (widthScaledRatio > heightScaledRatio) {
// //use heightScaledRatio
// width = (int) (res[0] * heightScaledRatio);
// height = screenRes[1];
// } else {
// //use widthScaledRatio
// width = screenRes[0];
// height = (int) (res[1] * widthScaledRatio);
// }
// Log.d(TAG, "width " + width + ",height:" + height);
// updateSurfaceView(width, height);
// FFMPEGPlayer.libSetup(width, height);
// playMedia();
//
// photoViewAttacher = new PhotoViewAttacher(surfaceView, width, height);
// photoViewAttacher.setScaleType(ImageView.ScaleType.CENTER_CROP);
// photoViewAttacher.setOnMatrixChangeListener(this);
// photoViewAttacher.update();
// }catch (Exception e){
//
// }
// }
// private void playMedia() {
//
// try{
// if(progressBar.getVisibility()==View.VISIBLE){
// progressBar.setVisibility(View.GONE);
// }
// FFMPEGPlayer.libPlay();
// isPlaying = true;
// CamerasActivity.isPlaying=true;
// }catch (Exception e){
//
// }
// }
// @DebugLog
// private void updateSurfaceView(int pWidth, int pHeight) {
// //update surfaceview dimension, this will cause the native window to change
// Log.d("ANURAN UPDATE SURFACE", "width " + pWidth + ",height:" + pHeight);
// FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) surfaceView.getLayoutParams();
// params.width = pWidth;
// params.height = pHeight;
// surfaceView.setLayoutParams(params);
// }
@Override
public void onBackPressed() {
if(backCounter==1){
super.onBackPressed();
}else{
//surface.release();
StreamingActivity.isFullScreenDisplayed=0;
surfaceView.getSurfaceTexture().release();
//ffmpegPlayer.libSetSurface(null);
if(this.surface !=null){
this.surface.release();
this.surface=null;
}
backCounter++;
Toast.makeText(FullScreenActivity.this,"Press back again to quit full screen",Toast.LENGTH_SHORT).show();
}
}
@DebugLog
@SuppressLint("NewApi")
private int[] getScreenRes() {
int[] res = new int[2];
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
res[0] = size.x;
res[1] = size.y;
return res;
}
private void stopPlaying() {
isPlaying = false;
try{
ffmpegPlayer.libStop();
}catch (Exception e){
}
}
@Override
public void onStop() {
super.onStop();
fromADorSL=true;
}
@Override
public void onResume() {
super.onResume();
if(fromADorSL){
ffmpegPlayer.libSetSurface(null);
ffmpegPlayer.libSetSurface(this.surface);
}
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
//Toast.makeText(FullScreenActivity.this,"SurfaceTexture available",Toast.LENGTH_SHORT).show();
//updateSurfaceView(width, height);
try{
this.surface=new Surface(surface);
ffmpegPlayer.libSetup(width, height);
ffmpegPlayer.libSetSurface(this.surface);
photoViewAttacher = new PhotoViewAttacher(surfaceView, width, height);
photoViewAttacher.setScaleType(ImageView.ScaleType.CENTER_CROP);
photoViewAttacher.setOnMatrixChangeListener(this);
photoViewAttacher.update();
progressBar.setVisibility(View.INVISIBLE);
angleView.setVisibility(View.VISIBLE);
}catch (Exception e){
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
try{
Toast.makeText(FullScreenActivity.this,"SurfaceTexture changed",Toast.LENGTH_SHORT).show();
if (photoViewAttacher != null ) {
photoViewAttacher.update ();
}
if(this.surface !=null){
this.surface.release();
}
this.surface=null;
this.surface=new Surface(surface);
ffmpegPlayer.libSetup(width,height);
ffmpegPlayer.libSetSurface(this.surface);
}catch (Exception e){
}
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
try{
// this.surface.release();
// this.surface=null;
surfaceView.getSurfaceTexture().release();
if(this.surface !=null){
this.surface.release();
this.surface=null;
}
//ffmpegPlayer.libSetSurface(null);
}catch (Exception e){
}
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
if(this.surface !=null){
this.surface.release();
this.surface=null;
this.surface=new Surface(surface);
}
}
@Override
public void onMatrixChanged(Matrix matrix, RectF rectF) {
float maxMovement = (rectF.width() - surfaceView.getWidth());
float middle = surfaceView.getWidth() * 0.5f + surfaceView.getLeft();
float currentMiddle = rectF.width() * 0.5f + rectF.left;
float angle=(-(int) ((currentMiddle - middle) * 100 / maxMovement));
Log.d("ANURAN",angle+"");
angleView.setCurrentProgress((int)angle);
}
// public class PlayVideo extends AsyncTask<Void,Void,Void> {
//
// @Override
// protected Void doInBackground(Void... voids) {
// try{
// isInitialized=(FFMPEGPlayer.libInit(url)==0);
// }catch (Exception e){
// e.printStackTrace();
// }
// return null;
// }
//
// @Override
// protected void onPostExecute(Void aVoid) {
// super.onPostExecute(aVoid);
// postInit();
// this.cancel(true);
// }
// }
}