RTSP 实时视频流

Posted

技术标签:

【中文标题】RTSP 实时视频流【英文标题】:RTSP live video streaming 【发布时间】:2016-04-30 08:43:03 【问题描述】:

我正在构建一个应用程序,用于将视频从树莓派实时流式传输到我的 android 设备。我有三种播放此流的功能方式:

rtsp://media.smart-streaming.com/mytest/mp4:sample_phone_150k.mp4

    媒体播放器 + SurfaceView 视频查看 Intent.ACTION_VIEW

问题是应用程序播放上述^流但不播放我的 (rtsp://192.168.1.143:8554/vid.mp4) ... 但 VLC 可以。。 p>

我尝试过使用 VLC 和 LIVE555 以多种视频格式进行流式传输,我还尝试过播放手机上录制的视频。

这是我的代码:

//Stream methods 0 = MediaPlayer & SurfaceView, 1 = VideoView, 2 = Native Video Player
final int STREAM_USING = 0;

//MediaPlayer on surfaceView
String streamPath = "rtsp://192.168.1.143:8554/vid.mp4";//"rtsp://media.smart-streaming.com/mytest/mp4:sample_phone_150k.mp4";//"rtsp://192.168.1.143:8554/vid.mp4";//;"rtp://239.255.0.1:5004/";
Uri streamUri;
private MediaPlayer mediaPlayer;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;

//VideoView
VideoView videoView;

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

    //MediaPlayer
    switch (STREAM_USING) 
        case 0: 
            surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
            surfaceHolder = surfaceView.getHolder();
            surfaceHolder.setFixedSize(800, 480);
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            mediaPlayer = new MediaPlayer();

            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() 
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) 
                    if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) 
                        mediaPlayer.release();
                        mediaPlayer = new MediaPlayer();
                        //mediaPlayer.stop();
                        play();
                    
                    return false;
                
            );

            mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() 
                @Override
                public void onBufferingUpdate(MediaPlayer mp, int percent) 
                    Toast.makeText(getApplicationContext(), "BUFF : " + percent, Toast.LENGTH_SHORT).show();
                    if (!mediaPlayer.isPlaying()) 
                        mediaPlayer.start();
                    
                
            );

            //Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            //i.setType("video/*");
            //startActivityForResult(i, 1234);
            streamUri = Uri.parse(streamPath);
            play();
            break;
        
        case 1: 
            videoView = (VideoView) findViewById(R.id.videoView);
            videoView.setVideoURI(Uri.parse(streamPath));
            MediaController mediaController = new MediaController(this);
            //mediaController.setAnchorView(videoView);
            videoView.setMediaController(mediaController);
            videoView.requestFocus();
            try 
                videoView.start();
            
            catch (SecurityException se) 
                Log.e("SE", se.getMessage());
                se.printStackTrace();
            
            break;
        
        case 2: 
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(streamPath));
            startActivity(intent);
            break;
        
        default: 
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(streamPath));
            startActivity(intent);
        
    


private void play() 
    try 
        //final FileInputStream fis = new FileInputStream(streamPath);
        mediaPlayer.stop();
        mediaPlayer.reset();
        mediaPlayer.setDataSource(MainActivity.this, streamUri);
        //mediaPlayer.setAudiostreamType(AudioManager.STREAM_MUSIC);

        mediaPlayer.prepareAsync();
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 
            @Override
            public void onPrepared(MediaPlayer mp) 
                //mediaPlayer.reset();
                mediaPlayer.start();
            
        );


     catch (SecurityException se) 
        Log.e("SE", se.getMessage());
        se.printStackTrace();
     catch (IOException ie) 
        ie.printStackTrace();
    

感谢您的帮助,我已经尝试了一个星期来让它工作但没有成功:(

【问题讨论】:

当您尝试加载该 rtsp uri 时,提供 android 媒体 api 的 logcat 怎么样?媒体播放器和/或视频视图用它做什么? 好的,我明天再来 抱歉回复晚了:RTP 案例:E/MediaPlayer﹕ Error (1, -1003) RTSP 案例:E/MediaPlayer﹕ Error (1, -2147483648) @ciprianoss : 你需要什么好的媒体播放器来播放它吗?并且您确定您要播放的任何内容都是正确的流 url 并且可以在任何浏览器中正常工作吗? 【参考方案1】:

您已经添加了两种方式,只是我想添加位修改。我已经完成了流式传输任务。我已经将 rtsp 与 wowza 一起使用。我会让你知道的方式很少

尝试一次,如果您遇到问题,请告诉我。如果您在 vlc 中的流媒体工作正常,那么应用程序端有问题。如果这些方法不起作用,请尝试使用其他手机。对你也有帮助。

1.试试videoview

vvVideoPlay = (VideoView) findViewById(R.id.vvVideoPlay);
MediaController mediaController = new MediaController(this);

String videoUrl = "rtsp://192.168.1.143:8554/vid.mp4";

    mediaController.setAnchorView(vvVideoPlay);
    Uri uri = Uri.parse(videoUrl);
    vvVideoPlay.setVideoURI(uri);
    vvVideoPlay.setMediaController(mediaController);
    vvVideoPlay.requestFocus();

    vvVideoPlay.setOnPreparedListener(new OnPreparedListener() 

        @Override
        public void onPrepared(MediaPlayer mp) 

            mp.start();
            pdialog.dismiss();
            mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() 

                @Override
                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) 

                    mp.start();
                
            );
        
    );

2。直接用手机播放器试试

startActivity(new Intent(Intent.ACTION_VIEW,
                Uri.parse("rtsp://192.168.1.143:8554/vid.mp4")));

3.第三种方法尝试在您的应用中使用此库与自定义播放器。

第 1 步。 将其添加到您的 gradle 中

compile "fm.jiecao:jiecaovideoplayer:4.7.0"

Step2.将其添加为您在 xml 布局中播放的视频。

<fm.jiecao.jcvideoplayer_lib.JCVideoPlayerStandard
    android:id="@+id/videoPlayer"
    android:layout_
    android:layout_ />

第 3 步。 从这里查看如何在您的班级中使用此库,

public class PlayVideoActivity extends BaseActivity 

@BindView(R.id.videoPlayer)
JCVideoPlayerStandard mVideoPlayer;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    restoreFromIntent(getIntent());


@Override
public int getLayout() 
    return R.layout.activity_play_video;



// get video path from intent and play the video here
private void restoreFromIntent(Intent intent) 

    mVideoPlayer.setUp("rtsp://192.168.1.143:8554/vid.mp4"
            , JCVideoPlayerStandard.SCREEN_LAYOUT_LIST, "");


@Override
public void onBackPressed() 
    if (JCVideoPlayer.backPress()) 
        return;
    
    super.onBackPressed();


@Override
protected void onPause() 
    super.onPause();
    JCVideoPlayer.releaseAllVideos();


希望这能帮助您解决问题。谢谢

【讨论】:

感谢您的回答,我今天晚些时候会尝试一下,看看它是否有效。我不认为你理解了什么,我可以用 VLC 播放我的流,但不能用我自己的代码播放,但是测试链接流在所有情况下都用我的代码播放。 是的,我明白了你的意思,所以我给你一些提示。它有助于弄清楚和容易调试你的代码。 好的,我正在尝试我今天找到的一个选项,然后我会试试你的 是的,如果您有任何问题,请告诉我。 请交叉检查您要播放的网址

以上是关于RTSP 实时视频流的主要内容,如果未能解决你的问题,请参考以下文章

vlc-android-sdk - 无法查看 RTSP 实时视频

web无插件播放视频之rtsp

RTSP/Onvif视频平台EasyNVR手机端实时调阅菜单缺失情况的优化

WEB页面实时播放海康大华等摄像头RTSP视频流完全方案

十分钟搞定——基于OpenCV+Flask的网络实时读取RTSP视频流

既然不再支持 VLC 插件,如何在 Firefox 和 Chrome 中流式传输 RTSP 实时视频?