MediaPlayer播放声音但不播放视频 [英] MediaPlayer playing sound but not video

查看:112
本文介绍了MediaPlayer播放声音但不播放视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用SurfaceView从Android播放视频.

I'm trying to play a video from Android using a SurfaceView.

我可以加载视频,声音可以正确播放,但是看不到视频.

I can load the video, the sound is played correctly but I can't see the video.

这是我的活动:

public class VideoTest extends Activity implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback, OnErrorListener {

    private static final String TAG = "MediaPlayerDemo";
    private int mVideoWidth;
    private int mVideoHeight;
    private MediaPlayer mMediaPlayer;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
    private String path;
    private Bundle extras;
    public static final String MEDIA = "media";
    private static final int LOCAL_AUDIO = 1;
    public static final int STREAM_AUDIO = 2;
    private static final int RESOURCES_AUDIO = 3;
    private static final int LOCAL_VIDEO = 4;
    public static final int STREAM_VIDEO = 5;
    private boolean mIsVideoSizeKnown = false;
    private boolean mIsVideoReadyToBePlayed = false;
    private RelativeLayout layout;

    /**
     *
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        mPreview = new SurfaceView(this);
        holder = mPreview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        extras = getIntent().getExtras();

        mPreview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        layout = new RelativeLayout(this);
        layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
        layout.addView(mPreview, 0);

        setContentView(layout);

    }

    private void playVideo(Integer Media) {
        doCleanUp();
        try {
            mMediaPlayer = MediaPlayer.create(this, R.raw.video);
            mMediaPlayer.setDisplay(holder);

            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.setOnVideoSizeChangedListener(this);
            mMediaPlayer.setOnErrorListener(this);

            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

        } catch (Exception e) {
            Log.e(TAG, "error: " + e.getMessage(), e);
        }
    }

    public void onBufferingUpdate(MediaPlayer arg0, int percent) {
        Log.d(TAG, "onBufferingUpdate percent:" + percent + " pos : " + mMediaPlayer.getCurrentPosition() + " / " + mMediaPlayer.getDuration());
        if (mMediaPlayer.isPlaying()) {
            Log.d(TAG, "Playing");
        } else {
            mMediaPlayer.start();
        }
    }

    public void onCompletion(MediaPlayer arg0) {
        Log.d(TAG, "onCompletion called");
    }

    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        Log.v(TAG, "onVideoSizeChanged called");
        if (width == 0 || height == 0) {
            Log.e(TAG, "invalid video width(" + width + ") or height(" + height
                    + ")");
            return;
        }
        mIsVideoSizeKnown = true;
        mVideoWidth = width;
        mVideoHeight = height;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback();
        }
    }

    public void onPrepared(MediaPlayer mediaplayer) {
        Log.d(TAG, "onPrepared called");
        mIsVideoReadyToBePlayed = true;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback();
        }
    }

    public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
        Log.d(TAG, "surfaceChanged called. Width : " + j + ", height : " + k);
        holder = surfaceholder;
        mMediaPlayer.setDisplay(holder);
        mIsVideoSizeKnown = true;
        mVideoWidth = j;
        mVideoHeight = k;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback();
        }
    }

    public void surfaceDestroyed(SurfaceHolder surfaceholder) {
        Log.d(TAG, "surfaceDestroyed called");
    }

    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated called");
        playVideo(extras.getInt(MEDIA));

    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaPlayer();
        doCleanUp();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseMediaPlayer();
        doCleanUp();
    }

    private void releaseMediaPlayer() {
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    private void doCleanUp() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mIsVideoReadyToBePlayed = false;
        mIsVideoSizeKnown = false;
    }

    private void startVideoPlayback() {
        Log.v(TAG, "startVideoPlayback " + mVideoWidth + "x" + mVideoHeight);

        int width = mPreview.getWidth();
        int height = mPreview.getHeight();
        float boxWidth = width;
        float boxHeight = height;

        float videoWidth = mMediaPlayer.getVideoWidth();
        float videoHeight = mMediaPlayer.getVideoHeight();

        Log.i(TAG, String.format("startVideoPlayback @ video %dx%d - box %dx%d", (int) videoWidth, (int) videoHeight, width, height));

        float wr = boxWidth / videoWidth;
        float hr = boxHeight / videoHeight;
        float ar = videoWidth / videoHeight;

        if (wr > hr) {
            width = (int) (boxHeight * ar);
        } else {
            height = (int) (boxWidth / ar);
        }

        Log.i(TAG, String.format("Scaled to %dx%d", width, height));

        holder.setFixedSize(width, height);
        mMediaPlayer.start();
    }

    public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
        Log.e(TAG, "ERROR called : " + arg1 + ", " + arg2);
        return false;
    }
}

从不调用onVideoSizeChanged函数,但调用onPreparedsurfaceChanged. 因此调用了startVideoPlayback函数,但视频的宽度和高度均为0.

The onVideoSizeChanged function is never called but the onPrepared and surfaceChanged are called. Thus the startVideoPlayback function is called, but the video width and height are 0.

我正在播放视频,因为我可以听到声音,但是屏幕上什么都没有显示. 我还尝试为SurfaceHolder对象的setFixedSize函数提供原始宽度和高度,但仍然没有显示任何内容.

My video is playing, as I can hear the sound, but nothing is displayed on the screen. I also tried to give raw width and height to the setFixedSize function of the SurfaceHolder object but I still don't have anything displayed.

你能帮我吗? 我正在使用Android 8

Can you help me? I'm using Android 8

编辑

这是我从资源中播放视频时的日志:

Here is the log I have when I'm playing a video from the resources :

WARN    info/warning (1, 35)
WARN    info/warning (1, 44)
DEBUG   Duration : 101248
DEBUG   surfaceChanged called. Width : 480, height : 270
INFO    Info (1,35)
INFO    Info (1,44)
DEBUG   onPrepared called
VERBOSE startVideoPlayback 480x270
INFO    startVideoPlayback @ video 0x0 - box 480x270
INFO    Scaled to 480x0
DEBUG   surfaceDestroyed called

编辑2

我尝试了另一个视频,并且可以正常工作.

I tried with another video and it's working.

以下是无效"视频的规格:

Here are the specifications of the "not working" video :

  • 容器:MP4-QuickTime
  • 速率:2340 Kbps
  • 格式:H.264/MPEG-4-AVC
  • 大小:1280 * 640
  • 纵横像素:未定义
  • 图片比例:2.000
  • 编码配置文件:Baseline@L3.1
  • Container : MP4 - QuickTime
  • Rate : 2 340 Kbps
  • Format : H.264/MPEG-4-AVC
  • Size : 1280*640
  • Aspect pixel : undefined
  • Image proportion : 2.000
  • Encoding profile : Baseline@L3.1

以下是工作视频的规格:

Here are the specifications for the working video :

  • 容器:MP4-QuickTime
  • 费率:537 Kbps
  • 格式:H.264/MPEG-4-AVC
  • 大小:640 * 360
  • 纵横像素:未定义
  • 图像比例:16:9
  • 编码配置文件:基准@ L3.0
  • Container : MP4 - QuickTime
  • Rate : 537 Kbps
  • Format : H.264/MPEG-4-AVC
  • Size : 640*360
  • Aspect pixel : undefined
  • Image proportion : 16:9
  • Encoding profile : Baseline@L3.0

您知道第一个视频出了什么问题吗?

Do you know what's wrong with the first video ?

推荐答案

可尝试的一些方法:

1)您是否应该在playVideo方法中调用mMediaPlayer.prepareAsync()?

1) Should you be calling mMediaPlayer.prepareAsync() in your playVideo method?

2)尝试删除onPrepared中的if语句

2) Try removing your if statement in onPrepared

3)我会打电话给holder.setSizeFromLayout();然后从onPrepared回调(而不是onBufferingUpdate)中选择mMediaPlayer.start().

3) I would call holder.setSizeFromLayout(); and then mMediaPlayer.start() from your onPrepared callback (rather than onBufferingUpdate).

这篇关于MediaPlayer播放声音但不播放视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆