【问题标题】:Play m3u8 video in android在android中播放m3u8视频
【发布时间】:2012-01-06 09:21:54
【问题描述】:

我想直播视频,它是 m3u8 格式。所以我尝试了下面的代码

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

    private static final String TAG = StreamingPlayer.class.getSimpleName();
    private int mVideoWidth;
    private int mVideoHeight;
    private MediaPlayer mMediaPlayer;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
    private String path;

    private boolean mIsVideoSizeKnown = false;
    private boolean mIsVideoReadyToBePlayed = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mediaplayer_2);
        mPreview = (SurfaceView) findViewById(R.id.surface);
        holder = mPreview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    private void playVideo() {
        doCleanUp();
        try {

            /*
             * TODO: Set path variable to progressive streamable mp4 or
             * 3gpp format URL. Http protocol should be used.
             * Mediaplayer can only play "progressive streamable
             * contents" which basically means: 1. the movie atom has to
             * precede all the media data atoms. 2. The clip has to be
             * reasonably interleaved.
             * 
             */

            path = "httplive://xboodangx.api.channel.livestream.com/3.0/playlist.m3u8";

            if (path == "") {
                // Tell the user to provide a media file URL.
                Toast
                .makeText(
                        this,
                        "Please edit MediaPlayerDemo_Video Activity,"
                        + " and set the path variable to your media file URL.",
                        Toast.LENGTH_LONG).show();
            } 

            Log.e("PATH", "Path = " + path);
            // Create a new media player and set the listeners
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(path);
            mMediaPlayer.setDisplay(holder);
                    mMediaPlayer.setOnBufferingUpdateListener(this);
                    mMediaPlayer.setOnPreparedListener(this);
            mMediaPlayer.prepare();
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnVideoSizeChangedListener(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);

    }

    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");

    }

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


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

    }

    @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");
        holder.setFixedSize(mVideoWidth, mVideoHeight);
        mMediaPlayer.start();
    }


}

在 logcat 中显示 onBufferingUpdate percent:100 但我看不到视频。

音频正在工作,但突然被击中。

我尝试了这个视频链接http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8 它正在工作。但是我的视频链接不起作用,我更改了httplive://... instead of http://,但没有用。

我也看到了这个答案Android video stream mms and m3u8

在上面的链接中显示视频无法播放消息。

【问题讨论】:

  • 你试过在真机上测试它吗?有时模拟器在处理 HTTP Live Streaming 时很糟糕。
  • @yorkw 感谢您的回复。是的,我在真实设备中测试,而不是在模拟器中。
  • URI h t t p://myvideo.m3u8 对我来说很奇怪,你在哪里托管媒体?远程服务器?如果您可以访问服务器端的广播代码,请尝试将其更改为更可靠的 URL,例如 h t t p://domain-name/service-name/myvideo.m3u8。不确定这是否可行,但值得一试。
  • 此代码有效还是修复问题之前的版本?

标签: android http-live-streaming


【解决方案1】:

视频存在于http://www.livestream.com。其中有用于直播的 Mobile Api。

API 是:

http://www.livestream.com/userguide/index.php?title=Mobile_API#How_to_get_mobile_compatible_clips_from_a_channel.27s_library

在上面的链接中有移动兼容的完整信息。从频道获取rtsp链接以使用此链接

http://xproshowcasex.channel-api.livestream-api.com/2.0/getstream

替换您的频道名称,而不是 proshowcase。然后获取所有移动兼容的 url,如 iPhone、Android、Blackberry 等,

使用该网址,您可以使用视频视图或媒体播放器在 Android 中流式传输视频。

有关更多信息,请阅读 Mobile Api 链接。

如果有人遇到同样的问题,希望这个答案对你有所帮助。

祝你好运。

【讨论】:

  • @GuillermoVarini 上面的代码对我不起作用。请阅读我的答案并详细告诉我您的问题,如果我知道,我会告诉您答案。
  • 问题是我需要在 2.1 应用程序上播放 m3u8 视频,但我找不到如何做到这一点的真实示例。在这里找到 2 个帖子,但没有用。还检查了 developer.android.com/ 但什么也没有:你说这个 api 有效吗?有如何实施的例子吗?
  • 实际上我的视频存在于 livestream.com 所以为此我已经有一个 api 我已经在上面发布了该 api 链接。从这里我得到了 rtsp 链接,然后我使用视频视图播放了 rtsp 链接视频
【解决方案2】:

播放流没有问题:

videoView1.setVideoPath("http://***.net/livedemo/_definst_/stream3.stream/playlist.m3u8?wowzasessionid=773395207");
videoView1.start();

关于消息:

视频无法播放

也许你需要为你的 Manifest 文件添加权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

【讨论】:

  • 不是必须的。
  • 同样的问题。你找到解决办法了吗?
【解决方案3】:

我认为你应该移动这个:

mMediaPlayer.setOnPreparedListener(this);

在打电话给prepare()之前

【讨论】:

  • 感谢您的回复。我实现了您的想法,但它不起作用。直到它显示 onBufferingUpdate percent:100 并且我看不到视频
【解决方案4】:

您是否尝试通过网络浏览器直接使用本机播放器播放您的链接? 如果您无法使用原生播放器播放,则表示您当前的 Android 版本不支持您的文件。 HTTP Live Streaming 格式可能有一些特殊性,Android 不能很好地支持,但它可以在 IOS 上播放。

【讨论】:

  • 感谢您的回复。它正在运行它 android 原生播放器和 IOS 也是。已经完成了这项任务。
【解决方案5】:

我尝试了6个多月的m3u8视频格式,没有成功。它在我的 iPhone 应用程序和本机应用程序中播放。我的流媒体服务器是 Red5,它没有 RTSP 插件。它发出 RTMP 流,无法在 Android 中流式传输。我等了一年才获得支持 RTSP 流的操作系统,但谷歌没有。我仍然使用带有 Flash 播放器的网络视图来流式传输实时视频(它不太清晰)。对我的客户这么说并继续搜索以在 Android 默认播放器中播放直播流,我感到很惭愧。

我认为您的视频网址可能不是 RTSP。

【讨论】:

    【解决方案6】:

    如何在 Android 中播放 .M3U8 流媒体

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    
        <VideoView
            android:id="@+id/myVideoView"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    

    Main.java

    package com.grexample.ooyalalive;
    
    import java.net.URL;
    import android.app.Activity;
    import android.net.Uri;
    import android.os.Bundle;
    import android.widget.MediaController;
    import android.widget.VideoView;
    
    public class Main extends Activity {
    
        private String urlStream;
        private VideoView myVideoView;
        private URL url;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main_vv);//***************
                myVideoView = (VideoView)this.findViewById(R.id.myVideoView);
                MediaController mc = new MediaController(this);
                myVideoView.setMediaController(mc);         
                urlStream = "http://jorgesys.net/i/irina_delivery@117489/master.m3u8";
    
                myVideoView.setVideoURI(Uri.parse(urlStream)); 
    
        }
    }
    

    我看到很多人在播放 .M3U8 时遇到问题,这取决于用于流式传输的编解码器以及与设备的兼容性,例如,我的一些 .m3u8 文件仅在屏幕为 1200 x800 和更高。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 2014-02-12
      相关资源
      最近更新 更多