我的应用程序显示一项活动,允许用户在图形上触摸最多五个点,每个点都显示不同的图形动画。通过使用MediaPlayer显示.mp4文件来提供动画。
当动画播放时,我的挂机就会出现。在.mp4开始播放之前,会显示一个简短的白屏。我尝试了一些方法来显示视频,所有这些方法都基于MediaPlayer:VideoView,SurfaceView和TextureView。
此问题最常见的建议答案是在MediaPlayer使用的任何View后面显示一个View,以显示其视频,其中包含从视频的第一帧绘制的背景。在视频开始播放之前,建议使视频的视图可见并隐藏背景图像视图。但是这些方法并不相关,因为它们基于MediaPlayer;短暂的白色屏幕仍然存在。
这是我的基本设置:
AnimationLauncherFragment包含RelativeLayout,其背景设置为5个透明按钮的动画的第一帧。每个按钮都有一个OnClickListener,它用AnimationFragment替换AnimationLauncherFragment。
AnimationFragment包含一个TextureView,并实现了TextureView.OnSurfaceListener和MediaPlayer.OnCompletionListener。当曲面可用时,将运行onSurfaceTextureAvailable()的回调。这是我的实施:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_animationlauncher, container, false);
textureView = (TextureView) rootView.findViewById(R.id.animation);
textureView.setSurfaceTextureListener(this);
return rootView;
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
MediaPlayer player = MediaPlayer.create(getActivity(), R.raw.bdleft);
player.setOnCompletionListener(this);
player.setSurface(new Surface(surfaceTexture));
player.start();
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.stop();
mediaPlayer.release();
//also calls an OnAnimationCompleteListener to notify the Activity
//that the animation is complete so it can pop the backstack
}
我已经对导致白屏的原因进行了一些研究,从LogCat输出开始:
01-09 11:02:27.378 8086-8086/com.turbogunhawk.android.app V/MediaPlayer﹕ setVideoSurfaceTexture
01-09 11:02:27.658 8086-8086/com.turbogunhawk.android.app V/MediaPlayer﹕ setVideoSurfaceTexture
创建MediaPlayer时,它会在启动视频之前调用setVideoSurfaceTexture twices,一次调用方法.setDataSource(),一次调用.setSurface()。谷歌搜索带我到this有用的博客文章,在那里我找到了如何创建MediaPlayers的解释:
在setVideoSource和setAudioSource之后,现在MediaPlayerService将会 为将来的视频渲染分配SurfaceTexture(连接到 SurfaceFlinger的)
在Media Framework中:android_src \ framework \ basemedia \ libmediaplayerservice \ MediaPlayerService.cpp
status_t MediaPlayerService::Client::setVideoSurfaceTexture(const sp& surfaceTexture) {
LOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
sp p = getPlayer();
sp anw;
if (surfaceTexture != NULL) {
anw = new SurfaceTextureClient(surfaceTexture);
status_t err = native_window_api_connect(anw.get(), NATIVE_WINDOW_API_MEDIA);
}
status_t err = p->setVideoSurfaceTexture(surfaceTexture);
return err;
}
我的猜测是白色闪光是由创建MediaPlayer时分配的SurfaceTexture引起的,随后被抛弃或被属于实际显示的View的SurfaceTexture所取代。
我的问题是如何在用户点击触摸点时无缝显示视频。是否有替代MediaPlayer / MediaPlayerService来显示视频?