Android:播放Rtsp视频流的两种方式

一.SurfaceView + Mediaplayer

XML 中添加SurfaceView:

XML 复制代码
<SurfaceView
    android:id="@+id/surface_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Activity代码:

java 复制代码
package com.android.rtsp;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;

import com.android.rtsp.R;

public class RtspActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener {

    private final String TAG = this.getClass().getSimpleName();

    private MediaPlayer mediaPlayer;
    private SurfaceView surfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_rtsp);

        surfaceView = findViewById(R.id.surface_view);
        SurfaceHolder holder = surfaceView.getHolder();
        holder.addCallback(sfvCallBack);
    }

    private SurfaceHolder.Callback sfvCallBack = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            playVideo();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (mediaPlayer != null) {
                mediaPlayer.stop();
                mediaPlayer.release();
                mediaPlayer = null;
            }
        }
    };

    private void playVideo() {
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
            try {
                //公共Rtsp,后附多个目前可用的公共Rtsp
                mediaPlayer.setDataSource("rtsp://stream.strba.sk:1935/strba/VYHLAD_JAZERO.stream");
                mediaPlayer.setDisplay(surfaceView.getHolder());
                mediaPlayer.setOnPreparedListener(this);
                mediaPlayer.prepareAsync();
            } catch (Exception e) {
                e.printStackTrace();
                Toast.makeText(this, "Error loading video", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mediaPlayer.start();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

二.VideoView

源码可以看到,VideoViewSurfaceView 的封装,并且实现了MediaPlayerControl 的方法

所以本质还是SurfaceView+MediaPlayer

XML 添加VideoView:

XML 复制代码
<VideoView
    android:id="@+id/video_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Activity代码:

java 复制代码
package com.android.rtsp;

import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.VideoView;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;

import com.android.rtsp.R;

public class RtspActivity extends AppCompatActivity {

    private final String TAG = this.getClass().getSimpleName();

    private VideoView mVideoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_rtsp);

        mVideoView = findViewById(R.id.video_view);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mVideoView != null) {
            videoConfig();
        }
    }

    private void videoConfig() {
        //公共Rtsp,后附多个目前可用的公共Rtsp
        mVideoView.setVideoURI(Uri.parse("rtsp://stream.strba.sk:1935/strba/VYHLAD_JAZERO.stream"));

        //本质还是SurfaceView+MediaPlayer
        mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                Log.i(TAG, "onPrepared ... ........   ");
                mVideoView.requestFocus();
                mVideoView.start();
            }
        });

        //简化写法
        /*mVideoView.setOnPreparedListener(mp -> {
            mVideoView.requestFocus();
            mVideoView.start();
        });*/

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mVideoView.suspend();
    }
}

三.其他方式

网上也有很多自定义封装的viewplayer,也能方便快捷的实现Rtsp视频流的播放

可自行查阅

四.公共rtsp地址

目前暂时可用的Rtsp地址:

rtsp、rtmp测试地址_rtsp测试地址-CSDN博客

2025 rtsp测试拉流地址 - 简书

相关推荐
阿巴斯甜8 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker8 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95279 小时前
Andorid Google 登录接入文档
android
黄林晴11 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_1 天前
Android 启动优化方案
android
阿巴斯甜1 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇1 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android