问题
This happens on Android only. Videos work properly on iOS and Simulator.
The problem is that when my videos are loaded into the MediaPlayer, the displayed frame is and remains completely black. After pressing play, the video displays correctly. By pressing pause, the frame on which the pause occurred is shown correctly. However, if the app switches to background and then back to foreground, the paused video goes back to completely black.
How can I fix this problem?
The relevant part of my code is more or less as follows:
Media video = MediaManager.createMedia(videoFilePath, true, () -> {
Runnable callback = runOnVideoCompletion.get();
if (callback != null) {
callback.run();
}
});
video.setNativePlayerMode(false);
video.prepare();
MediaPlayer mediaPlayer = new MediaPlayer(video) {
@Override
public Dimension getPreferredSize() {
return new Dimension(size, size);
}
};
mediaPlayer.setHideNativeVideoControls(true);
mediaPlayer.setMaximize(false);
mediaPlayer.hideControls();
mediaPlayer.setAutoplay(false);
Container mediaPlayerCnt = new Container(new LayeredLayout(), "NoMarginNoPadding") {
@Override
public Dimension getPreferredSize() {
return new Dimension(size, size);
}
};
mediaPlayerCnt.add(mediaPlayer);
[...]
回答1:
UPDATE: please see the comment Reduce the impact of videos in memory to prevent crashes, since there is a better approach than the solution I proposed here.
While waiting for a proper solution, I came up with a workaround that seems to solve the problem perfectly on my Android phone.
This code is in a method invoked to create each video and is therefore executed before form.show()
, so the UITimer runnable is invoked about half a second after the form is shown.
/*
* Workaround for the issue: https://stackoverflow.com/q/66144759
* "video" is a Media instance returned by MediaManager.createMedia
* This workaround is for Android only and it assumes we don't use autoplay
*/
if (form != null && DeviceUtilities.isAndroidNative()) {
UITimer.timer(500, false, form, () -> {
CN.invokeAndBlock(() -> {
video.play();
video.setVolume(0);
while (!video.isPlaying()) {
/*
* When in a scrollable container there are many videos,
* play does not start immediately, but only when the
* video becomes visible, so we must wait.
*/
Util.sleep(100);
}
Util.sleep(100); // extra wait to be sure that the waiting is not zero
video.pause();
video.setVolume(100);
});
form.addShowListener(l -> {
CN.invokeAndBlock(() -> {
video.play();
video.setVolume(0);
while (!video.isPlaying()) {
// same as above
Util.sleep(100);
}
Util.sleep(100); // as above
video.pause();
video.setVolume(100);
});
});
});
}
来源:https://stackoverflow.com/questions/66144759/when-videos-are-just-loaded-or-paused-they-are-completely-black-on-android