【问题标题】:What exactly is a "Surface" class in Android?Android 中的“Surface”类到底是什么?
【发布时间】:2016-08-08 11:14:42
【问题描述】:

长期以来,我一直在尝试使用 MediaPlayer 类在“Surface”类上渲染视频。它正在播放音频,但不是视频。在我搜索的所有地方,人们都在谈论 SurfaceView 和 SurfaceHolder,但我只有一个 Surface 对象。如何破解这个拦截器?

我就是这样尝试的,

public class SampleVideoPlayer{

private Uri mUrl;
private Surface mSurface;
private MediaPlayer mMediaPlayer;
private Context mContext;

public SampleVideoPlayer(Context context, String url, Surface surface){
    mUrl = Uri.parse(url);
    mSurface = surface;
    mMediaPlayer = new MediaPlayer();
    mContext = context;
}

public void playVideo() throws IOException {
        mMediaPlayer.setDataSource(mContext, mUrl);
        mMediaPlayer.setSurface(mSurface);
        mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                mediaPlayer.start();
            }
        });
        mMediaPlayer.prepareAsync();
}

}

添加我正在传递的会话对象,

public class MyTvSession extends TvInputService.Session implements Handler.Callback {

Context mContext;
String vidUrl;
Surface mSurface;
SampleVideoPlayer player = null;
SampleMediaPlayer mediaPlayer;

public MyTvSession(Context context){
    super(context);
    ChannelXmlReader reader = new ChannelXmlReader(context);
    ArrayList<Channel> channels = reader.ReadXml();
    mContext = context;
    vidUrl = channels.get(0).url;
}
@Override
public boolean handleMessage(Message message) {
    Log.d("HANDLE MESSAGE", message.toString());
    return true;
}

@Override
public void onRelease() {

}

@Override
public boolean onSetSurface(Surface surface) {
    if(surface != null)
        Log.d("NOT NULL from SESSION", "NOTNULL");
    mSurface = surface;
    return true;
}

@Override
public void onSurfaceChanged(int format, int width, int height) {
    super.onSurfaceChanged(format, width, height);
    if(mediaPlayer != null)
        mediaPlayer.mMediaPlayer.setSurface(mSurface);

    Log.d("ONSURFACECHANGED", "Event");
}



@Override
public void onSetStreamVolume(float v) {

}

@Override
public boolean onTune(Uri uri) {
    Log.d("TUNING CHANNEL", uri.toString());
    try {
        mediaPlayer = new SampleMediaPlayer(mContext, vidUrl, mSurface);
        mediaPlayer.playVideo();
    }catch(Exception e){
        Log.d("MPEXCEPTION", Log.getStackTraceString(e));
    }
    return true;
}

@Override
public void onSetCaptionEnabled(boolean b) {

}

}

【问题讨论】:

  • 我已经阅读该页面很长时间了!我想知道如何让 MediaPlayer 在表面上播放视频!
  • 你的意思是setDisplay(SurfaceHolder sh)?
  • 请检查上面的代码。我有一个“表面”来绘制我的视频。不是 SurfaceHolder 或 SurfaceView
  • 所以使用setSurface(Surface surface)...你为什么不阅读MediaPlayer文档?

标签: android television


【解决方案1】:

Surface 类是一个围绕缓冲区列表的薄包装器,该缓冲区列表与负责渲染到显示器的支持 surfaceflinger 进程共享。

您可以使用SurfaceView 及其SurfaceHolder 获得其中之一,它们与视图的生命周期相关联。所以一定要在surface创建完成后被回调后获取。

或者,您可以使用SurfaceTexture,它是使用您自己的自定义 OpenGL 上下文创建的。通过这种方法,您可以使用自己的 OpenGL 代码进行渲染,甚至可以将其传递给媒体引擎进行渲染。您还可以使用TextureViewSurfaceTexture 绑定到视图子系统(但与SurfaceView 一样,您需要在其生命周期的适当时间使用它。)

【讨论】:

  • 感谢您的回答!但是,你能帮我解决我的问题吗? TvInputFramework 给了我一个“Surface”对象,我可以在上面绘制视频。我使用 MediaPlayer 并设置它的表面以在其上播放视频。但我只能听到音频内容,看不到任何视觉内容。
  • 你是怎么从电视输入层得到支持Surface的?
  • TvInputManager 将调用我的 onSetSurface(Surface surface) 实现,这就是我获取支持 Surface 对象的方式。
  • 您确定该应用实际上正在为您的服务会话提供有效的表面吗?
  • 是的,我确定!它不为空,它能够播放曲目的音频,每当我尝试强制关闭应用程序时,我都可以看到视频帧
【解决方案2】:

我也有同样的问题。但它只发生在飞利浦电视上。相同的代码在所有其他 Android TV 设备上运行良好。我在 onSetSurface 中得到的表面是有效的,声音正在播放,但画面是黑色的。当我关闭应用程序时,视频会显示一秒钟。它似乎在后台。

【讨论】:

  • 没错!即使我使用飞利浦电视。该特定品牌的电视存在一些问题。不过它在三星上运行良好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-01
  • 2015-09-19
  • 2012-12-05
  • 2010-11-15
  • 2014-04-11
  • 2012-02-15
  • 2018-01-19
相关资源
最近更新 更多