My App has a Fragment that's playing videos that are one second long. After a video is played the user has to press a button and then a new video is supposed to be played. Before playing the second video the my main activity loads creates a new fragment and creates new Exoplayer instance.
The first time I play the video everything works as expected. If I however want to play a second video, it shows a freezed image of the last frame of the first video and plays the sound of the second video. This bug doesn't appear on Android 8 (API level 26) but on versions below Android 8 (I tested Android 6 and Android 7.1).
Given that I have both a new Surface with the new Fragment and a new Exoplayer it's a mystery to me why there's still data for the last frame of the previous video. Is there some function I can call to delete that data and get the behavior I get in Android 8 where the second video plays without problems also in earlier versions of Android?
Before I used ExoPlayer the normal MediaPlayer had the same issue. I created a minimized example of the problem where I have:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mButton = findViewById(R.id.button1);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createNewFragment();
}
});
}
private void createNewFragment() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.contentFragment, new VideoFragment());
ft.commit();
}
}
public class VideoFragment extends Fragment implements SurfaceHolder.Callback{
private Context mContext;
private SimpleExoPlayer mPlayer;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.videolayout, container, false);
SurfaceView mSurfaceView = (SurfaceView) view.findViewById(R.id.surface_view1);
SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
surfaceHolder.setSizeFromLayout();
surfaceHolder.addCallback(this);
mContext = inflater.getContext();
return view;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
mPlayer = ExoPlayerFactory.newSimpleInstance(mContext, trackSelector);
mPlayer.setVideoSurfaceHolder(holder);
mPlayer.setPlayWhenReady(true);
playVideo(mContext);
}
private void playVideo(Context context){
final RawResourceDataSource rawResourceDataSource = new RawResourceDataSource(context);
int raw_res_id = context.getResources().getIdentifier(
"collect",
"raw",
context.getPackageName());
DataSpec dataSpec = new DataSpec(RawResourceDataSource.buildRawResourceUri(raw_res_id));
try {
rawResourceDataSource.open(dataSpec);
DataSource.Factory factory = new DataSource.Factory() {
@Override
public DataSource createDataSource() {
return rawResourceDataSource;
}
};
MediaSource media_source = new ExtractorMediaSource.Factory(factory).createMediaSource(rawResourceDataSource.getUri());
mPlayer.prepare(media_source);
} catch (RawResourceDataSource.RawResourceDataSourceException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
try to do the below code for fragmentchange
final FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment f = new VideoFragment();
transaction.replace(R.id.contentFragment, f).commit();
Just try this code and check if same occurs