gpt4 book ai didi

android - 是否可以在不停止流的情况下分离和重新附加 VideoView?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:24:39 27 4
gpt4 key购买 nike

我正在构建一个应用程序,用户可以在其中点击一个按钮来全屏显示视频。最初,视频附加到 ViewPager 内的 View 。为了能够全屏显示它,我将它从它的父 View 中分离出来并将它重新附加到 Root View 。这工作正常,除非视频在播放时切换到全屏。当我分离一个正在播放的 VideoView 时,它就停止了,我需要重新启动它。这是 Not Acceptable ,因为视频在恢复之前开始缓冲。这是完成分离的代码部分:

    final ViewGroup parent = (ViewGroup) findViewById(R.id.parent);

final ViewGroup root = (ViewGroup) findViewById(R.id.root);

Button b = (Button) findViewById(R.id.button);
b.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
parent.removeView(mVideoView);

LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
root.addView(mVideoView, lp);
}
});

根据设备的不同,我有不同的日志错误。可能是因为实际的视频播放器是由制造商提供的,而不是 Android SDK。以下是 Nexus 7 的错误日志:

10-30 20:26:18.618: D/NvOsDebugPrintf(124): NvMMDecTVMRDestroyParser Begin 
10-30 20:26:18.618: D/NvOsDebugPrintf(124): --------- Closing TVMR Frame Delivery Thread -------------
10-30 20:26:18.678: D/NvOsDebugPrintf(124): ------- NvAvpClose -------
10-30 20:26:18.678: D/NvOsDebugPrintf(124): NvMMDecTVMRDestroyParser Done
10-30 20:26:18.678: D/NvOsDebugPrintf(124): NvMMLiteTVMRDecPrivateClose Done

我无法在不停止的情况下分离视频。我尝试使用 SurfaceView 或 TextureView 但没有成功。

我还尝试寻找第三方视频播放器。我找到了一个商业的 ( http://www.vitamio.org/ ),出于商业原因我不能真正使用它。我找到了一个开源的,去年没有更新 ( https://code.google.com/p/dolphin-player/ )。

我目前只在平板电脑上定位 Android 4.2 或更高版本。


请注意,ViewPager 不是全屏的。所以我不能使用 LayoutParams 使视频全屏。我需要从 ViewPager 的父 View 中删除 VideoView 并将其添加到 Root View 以便能够全屏显示它。

我正在测试的 URL:http://bellvps1.cpl.delvenetworks.com/media/e1b3e24ecb944abd8f4ed823a0b76ddc/68f78d35296243bfb46d2418f03f2fd0/bande-annonce---the-secret-life-of-walter-mitty-1-9efcc5c6e52ac07a3edf84a1b21967995b7796a2.m3u8

最佳答案

可以使用 TextureView 实现此效果。基本上你所做的是创建一个 MediaPlayer 实例,prepare() 它并启动它,然后你可以使用 MediaPlayer.setSurface()任何 TextureView 上的方法在视频播放时更改表面,而不对 MediaPlayer 对象状态进行任何更改,如 android 文档中的 setSurface() 方法:

这个方法可以在任何状态下调用,调用它不会改变对象状态。

请注意此实现是为了演示,您可能应该使用 mediaplayer.prepareAsync() 并使用 onPreparedListener() 等待回调,您还将需要根据您的视频大小为第二个 TextureView 设置正确的尺寸,处理方向变化,当然还需要在需要时正确处理异常。

activity_main.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center"
android:background="#ff0000" />

<Button
android:id="@+id/btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:text="Switch to second surface" />

<TextureView
android:id="@+id/tv_full"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</FrameLayout>

主 Activity .java

public class MainActivity extends Activity {
private static final String VIDEO_URI = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";

private TextureView tvFull;
private MediaPlayer mp;

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mp = new MediaPlayer();
try {
mp.setDataSource(this, Uri.parse(VIDEO_URI));
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}

((ViewPager) findViewById(R.id.pager)).setAdapter(new PagerAdapter() {
@Override public int getCount() {
return 1;
}

@Override public boolean isViewFromObject(View view, Object o) {
return view == o;
}

@Override public Object instantiateItem(ViewGroup container, int position) {
final TextureView tv = new TextureView(MainActivity.this);

tv.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
tv.setSurfaceTextureListener(null);
mp.setSurface(new Surface(surfaceTexture));
mp.start();
}

@Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {}

@Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}

@Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}
});

if (tv.isAvailable()) {
tv.getSurfaceTextureListener().onSurfaceTextureAvailable(tv.getSurfaceTexture(),
tv.getWidth(), tv.getHeight());
}

container.addView(tv, 0);
return tv;
}

@Override public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
});

tvFull = (TextureView) findViewById(R.id.tv_full);

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
tvFull.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) {
tvFull.setSurfaceTextureListener(null);
mp.setSurface(new Surface(surfaceTexture));
}

@Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {

}

@Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}

@Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

}
});

if (tvFull.isAvailable()) {
tvFull.getSurfaceTextureListener().onSurfaceTextureAvailable(tvFull.getSurfaceTexture(),
tvFull.getWidth(), tvFull.getHeight());
}
}
});
}

@Override protected void onDestroy() {
mp.reset();
mp.release();

super.onDestroy();
}
}

关于android - 是否可以在不停止流的情况下分离和重新附加 VideoView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19696466/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com