首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Andorid平台实现高性能低延迟的多路RTSP播放器

Andorid平台实现高性能低延迟的多路RTSP播放器

原创
作者头像
音视频牛哥
发布于 2025-04-24 03:46:21
发布于 2025-04-24 03:46:21
13800
代码可运行
举报
运行总次数:0
代码可运行

​在当今的视频监控、流媒体传输等领域,RTSP(Real Time Streaming Protocol)协议被广泛用于音视频数据的实时传输。为了满足多路 RTSP 流的同时播放需求,基于大牛直播SDK开发了一款功能丰富、性能稳定的多路 RTSP 播放器。本文将深入解析该播放器的实现原理、代码架构以及关键功能模块。

一、项目背景与需求

随着视频监控系统的规模不断扩大,用户需要一个能够同时处理多路 RTSP 流的播放器,以实现对多个监控摄像头或流媒体源的集中监控与管理。传统的单路播放器已无法满足此类需求,因此开发一个多路 RTSP 播放器显得尤为必要。

该播放器主要面向以下场景:

  • 视频监控中心 :对多个监控摄像头进行实时监控,要求低延迟、高稳定性。
  • 流媒体服务器测试 :在测试流媒体服务器时,需要模拟多个客户端同时播放 RTSP 流,以评估服务器性能。
  • 多媒体展示系统 :在某些展览、展示场景中,需要在多个屏幕上同时播放不同的 RTSP 流媒体内容。

二、整体架构设计

(一)核心组件

  1. SDK 封装层 :利用大牛直播SDK的SmartMediakit框架提供的 SmartPlayerJniV2 类,通过 JNI 调用原生库实现 RTSP 流的底层处理,包括播放、截图、录像等功能。
  2. 播放器封装类(LibPlayerWrapper) :对 SDK 的功能进行二次封装,提供更简洁易用的接口,管理播放器的生命周期、状态以及与 SDK 的交互逻辑。
  3. UI 层(SmartPlayer) :基于 Android 的 Activity 构建,负责与用户交互,展示播放画面,控制播放器的启动、停止、录像等操作。

(二)架构图

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UI 层(SmartPlayer)
    │
    ├─ 播放控制(按钮点击事件)
    ├─ 播放画面展示(SurfaceView)
    └─ 事件显示(文本信息)
LibPlayerWrapper 层
    │
    ├─ 播放器生命周期管理
    ├─ 播放状态控制(播放、暂停、停止)
    ├─ 录像功能管理
    ├─ 截图功能实现
    └─ 事件回调处理
SDK 封装层(SmartPlayerJniV2)
    │
    ├─ RTSP 流处理(播放、暂停、停止)
    ├─ 视频渲染(Surface 设置)
    ├─ 音频处理
    ├─ 录像功能实现
    └─ 截图功能实现

三、关键代码解析

(一)播放器初始化

在 SmartPlayer 类的 onCreate 方法中,完成播放器的初始化工作。

代码语言:java
AI代码解释
复制
libPlayer = new SmartPlayerJniV2();
context_ = this.getApplicationContext();

initView();
initPlayUrls();
setupSurfaceCallbacks();
createPlayerInstances();
setupButtonListeners();

首先,创建 SmartPlayerJniV2 对象,这是与 SDK 进行交互的入口。接着,初始化 UI 组件,加载播放地址列表,并为 SurfaceView 设置回调函数。然后,创建多个 LibPlayerWrapper 实例,每个实例对应一个播放器实例,用于管理单个 RTSP 流的播放。

(二)播放控制

在 LibPlayerWrapper 类中,startPlayer 方法实现了播放功能。

代码语言:java
AI代码解释
复制
public boolean startPlayer(boolean is_hardware_decoder, boolean is_enable_hardware_render_mode, boolean is_mute) {
    if (is_playing()) {
        Log.e(TAG, "already playing, native_handle:" + get());
        return false;
    }

    setPlayerParam(is_hardware_decoder, is_enable_hardware_render_mode, is_mute);

    int ret = lib_player_.SmartPlayerStartPlay(get());
    if (ret != OK) {
        Log.e(TAG, "call StartPlay failed, native_handle:" + get() + ", ret:" + ret);
        return false;
    }

    write_lock_.lock();
    try {
        this.is_playing_ = true;
    } finally {
        write_lock_.unlock();
    }

    Log.i(TAG, "call StartPlayer OK, native_handle:" + get());
    return true;
}

在 startPlayer 方法中,首先检查播放器是否已经在播放状态。然后,通过 setPlayerParam 方法设置播放器参数,如硬件解码、硬件渲染模式和静音等。接着,调用 SDK 提供的 SmartPlayerStartPlay 方法开始播放 RTSP 流。如果播放成功,更新播放器的状态为正在播放。

(三)录像功能

LibPlayerWrapper 类中的 configRecorderParam 方法用于配置录像参数。

代码语言:java
AI代码解释
复制
public boolean configRecorderParam(String rec_dir, int file_max_size, int is_transcode_aac,
                                   int is_record_video, int is_record_audio) {

    if(!check_native_handle())
        return false;

    if (null == rec_dir || rec_dir.isEmpty())
        return false;

    int ret = lib_player_.SmartPlayerCreateFileDirectory(rec_dir);
    if (ret != 0) {
        Log.e(TAG, "Create record dir failed, path:" + rec_dir);
        return false;
    }

    if (lib_player_.SmartPlayerSetRecorderDirectory(get(), rec_dir) != 0) {
        Log.e(TAG, "Set record dir failed , path:" + rec_dir);
        return false;
    }

    if (lib_player_.SmartPlayerSetRecorderFileMaxSize(get(),file_max_size) != 0) {
        Log.e(TAG, "SmartPlayerSetRecorderFileMaxSize failed.");
        return false;
    }

    lib_player_.SmartPlayerSetRecorderAudioTranscodeAAC(get(), is_transcode_aac);

    // 更细粒度控制录像的, 一般情况无需调用
    lib_player_.SmartPlayerSetRecorderVideo(get(), is_record_video);
    lib_player_.SmartPlayerSetRecorderAudio(get(), is_record_audio);
    return true;
}

该方法首先检查原生句柄是否有效以及录像目录是否合法。然后,调用 SDK 的相关方法创建录像目录、设置录像文件最大大小、音频转码 AAC 参数以及是否录制视频和音频。通过这些参数的配置,可以灵活地控制录像的各个方面。

startRecorder 方法用于启动录像功能。

代码语言:java
AI代码解释
复制
public boolean startRecorder() {

    if (is_recording()) {
        Log.e(TAG, "already recording, native_handle:" + get());
        return false;
    }

    int ret = lib_player_.SmartPlayerStartRecorder(get());
    if (ret != OK) {
        Log.e(TAG, "call SmartPlayerStartRecorder failed, native_handle:" + get() + ", ret:" + ret);
        return false;
    }

    write_lock_.lock();
    try {
        this.is_recording_ = true;
    } finally {
        write_lock_.unlock();
    }

    Log.i(TAG, "call SmartPlayerStartRecorder OK, native_handle:" + get());
    return true;
}

在启动录像之前,检查是否已经在录像状态。然后,调用 SDK 的 SmartPlayerStartRecorder 方法开始录像,并更新播放器的录像状态。

(四)截图功能

LibPlayerWrapper 类中的 captureImage 方法实现了截图功能。

代码语言:java
AI代码解释
复制
public boolean captureImage(int compress_format, int quality, String file_name, String user_data_string) {
    if (!check_native_handle())
        return false;

    return OK == lib_player_.CaptureImage(get(), compress_format, quality, file_name, user_data_string);
}

该方法通过调用 SDK 的 CaptureImage 方法进行截图操作。参数包括压缩格式(JPEG 或 PNG)、图片质量、文件名和用户自定义字符串。用户可以根据需要选择截图的格式和质量,并指定截图保存的路径和文件名。

(五)事件回调

在 SmartPlayer 类中,实现了 EventListener 接口的 onPlayerEventCallback 方法,用于处理播放器的各种事件回调。

代码语言:java
AI代码解释
复制
@Override
public void onPlayerEventCallback(long handle, int id, long param1, long param2, String param3, String param4, Object param5) {
    StringBuilder sb = new StringBuilder(256);
    sb.append("PlayerHandle: ").append(handle).append(" ");

    switch (id) {
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
            sb.append("开始..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
            sb.append("连接中..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
            sb.append("连接失败..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
            sb.append("连接成功..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
            sb.append("连接断开..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
            sb.append("连接播放..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
            sb.append("分辨率信息: width: ").append(param1).append(", height: ").append(param2);
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
            sb.append("收不到媒体数据,可能是url错误..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_SWITCH_URL:
            sb.append("切换播放URL..");
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CAPTURE_IMAGE:
            sb.append("快照: ").append(param1).append(" 路径: ").append(param3);

            if (param1 == 0)
                sb.append("截取快照成功");
            else
                sb.append("截取快照失败");

            if (param4 != null && !param4.isEmpty())
                sb.append(", user data:").append(param4);
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RECORDER_START_NEW_FILE:
            sb.append("[record]开始一个新的录像文件 :").append(param3);
            break;
        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_ONE_RECORDER_FILE_FINISHED:
            sb.append("[record]已生成一个录像文件 :").append(param3);
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_START_BUFFERING:
            sb.append("Start Buffering");
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_BUFFERING:
            sb.append("Buffering: ").append(param1).append("%");
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STOP_BUFFERING:
            sb.append("Stop Buffering");
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_DOWNLOAD_SPEED:
            sb.append("download_speed:").append(param1).append("Byte/s, ").append((param1 * 8 / 1000)).append("kbps").append((param1 / 1024)).append("KB/s");
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RTSP_STATUS_CODE:
            Log.e(TAG, "RTSP error code received, please make sure username/password is correct, error code:" + param1);
            sb.append("RTSP error code: ").append(param1);
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_NEED_KEY:
            Log.e(TAG, "RTMP加密流,请设置播放需要的Key..");
            sb.append("RTMP加密流,请设置播放需要的Key..");
            break;

        case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_KEY_ERROR:
            Log.e(TAG, "RTMP加密流,Key错误,请重新设置..");
            sb.append("RTMP加密流,Key错误,请重新设置..");
            break;
    }

    Log.i(TAG, "onPlayerEventCallback: " + sb.toString());

    Message message = new Message();
    message.what = PLAYER_EVENT_MSG;
    message.obj =  sb.toString();
    handler_.sendMessage(message);
}

在该方法中,根据不同类型的事件 ID,构建相应的事件信息字符串,并通过 Handler 将事件信息发送到 UI 线程进行显示。这样用户可以在界面上实时查看播放器的各种状态变化和事件信息。

四、性能优化与注意事项

(一)硬件加速

在播放高清视频流时,开启硬件解码可以显著降低设备的 CPU 负载,提高播放性能。在 LibPlayerWrapper 类的 setPlayerParam 方法中,通过调用 SDK 的相关方法设置硬件解码和硬件渲染模式。

代码语言:java
AI代码解释
复制
if (is_hardware_decoder && is_enable_hardware_render_mode) {
    lib_player_.SmartPlayerSetHWRenderMode(get(), 1);
}

(二)低延迟模式

为了满足实时性要求较高的场景,可以启用低延迟模式。在 configurePlayer 方法中设置低延迟模式。

代码语言:java
AI代码解释
复制
boolean isLowLatency = true;
lib_player_.SmartPlayerSetLowLatencyMode(get(), isLowLatency ? 1 : 0);

(三)资源管理

在播放器的生命周期管理中,合理地分配和释放资源至关重要。在 LibPlayerWrapper 类的 release 方法中,释放播放器占用的资源。

代码语言:java
AI代码解释
复制
public void release() {
    if (empty())
        return;

    if(is_playing())
        stopPlayer();

    if (is_recording())
        stopRecorder();

    long handle;
    write_lock_.lock();
    try {
        handle = this.native_handle_;
        this.native_handle_ = 0;
        clear_all_playing_flags();
    } finally {
        write_lock_.unlock();
    }

    if (lib_player_ != null && handle != 0)
        lib_player_.SmartPlayerClose(handle);

    event_listener_ = null;
}

在释放资源时,先停止播放和录像操作,然后将原生句柄设置为 0,并调用 SDK 的 SmartPlayerClose 方法关闭播放器实例,最后将事件监听器设置为 null,避免内存泄漏。

(四)线程安全

在多线程环境下,对播放器状态和资源的访问需要保证线程安全。在 LibPlayerWrapper 类中,使用 ReentrantReadWriteLock 来保护对播放器状态和原生句柄的访问。

代码语言:java
AI代码解释
复制
private final ReadWriteLock rw_lock_ = new ReentrantReadWriteLock(true);
private final java.util.concurrent.locks.Lock write_lock_ = rw_lock_.writeLock();
private final java.util.concurrent.locks.Lock read_lock_ = rw_lock_.readLock();

在修改播放器状态或原生句柄时,获取写锁;在读取这些变量时,获取读锁,确保线程安全。

五、总结与展望

通过以上基于大牛直播 SDK 的多路 RTSP 播放器的实现与解析,我们深入了解了其架构设计、关键功能模块以及性能优化策略。该播放器具有以下优势:

  • 多路播放能力 :能够同时播放多路 RTSP 流,满足视频监控、流媒体测试等场景的需求。
  • 功能丰富 :支持播放、停止、截图、录像等多种功能,满足不同用户的使用需求。
  • 性能优化 :采用硬件加速、低延迟模式等技术手段,提高播放性能和实时性。
  • 良好的资源管理 :合理管理播放器的生命周期和资源,避免内存泄漏和资源浪费。

在未来的工作中,我们可以进一步扩展该播放器的功能,如支持更多的视频格式、实现自适应 bitrate 播放、优化在弱网络环境下的播放体验等。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android平台RTSP|RTMP播放器技术实践:基于大牛直播SDK的深度探索
在移动直播、视频监控等场景中,RTSP(Real Time Streaming Protocol)和 RTMP(Real Time Messaging Protocol)是两种常见的流媒体传输协议。它们能够提供实时、低延迟的音视频传输,但实现高效的播放功能具有一定技术门槛。大牛直播SDK作为行业内备受认可的解决方案,提供了功能强大、性能卓越的 RTSP/RTMP 播放模块。本文将基于大牛直播 SDK,详细讲解如何在 Android 平台开发一个高效的 RTSP|RTMP 播放器。
音视频牛哥
2025/04/25
3010
Android平台RTSP|RTMP播放器技术实践:基于大牛直播SDK的深度探索
Android平台RTSP|RTMP直播播放器技术接入说明
大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台为例,介绍下如何集成RTSP、RTMP播放模块。
音视频牛哥
2024/07/24
5130
Android平台RTSP|RTMP直播播放器技术接入说明
Android平台如何实现多路低延迟RTSP|RTMP播放?
实际上,我们在2015年做Android平台RTSP、RTMP播放模块的时候,第一版就支持了多实例播放,因为SDK设计比较灵活,做个简单的player实例封装即可实现多实例播放(Android Unity的就有多路demo),所以官方一直没有正式demo,本次也是有个开发者提到,希望测试下我们多路播放的效果,自己又不想做封装,索性给做个版本。
音视频牛哥
2024/06/17
1910
Android平台如何实现多路低延迟RTSP|RTMP播放?
Android平台RTSP|RTMP直播播放器技术接入说明
本文详细介绍了在 Android 平台上集成 RTSP 和 RTMP 直播播放模块的技术背景、系统要求、准备工作、接口设计、功能支持以及接口调用流程。通过合理的架构设计和优化,开发者可以高效地实现直播播放功能,满足不同场景下的应用需求。
音视频牛哥
2025/03/02
3221
Android平台RTSP|RTMP直播播放器技术接入说明
如何设计开发RTSP直播播放器?
我们在对接RTSP直播播放器相关技术诉求的时候,好多开发者,除了选用成熟的RTSP播放器外,还想知其然知其所以然,对RTSP播放器的整体开发有个基础的了解,方便方案之作和技术延伸。本文抛砖引玉,做个大概的介绍。
音视频牛哥
2024/10/12
4870
庖丁解牛之-Android平台RTSP|RTMP播放器设计
我们在做Android平台RTSP或者RTMP播放器开发的时候,需要注意的点非常多,以下,以大牛直播SDK(官方)的接口为例,大概介绍下相关接口设计:
音视频牛哥
2021/11/18
5480
Flutter下实现低延迟的跨平台RTSP/RTMP播放
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
音视频牛哥
2019/09/17
5K0
Flutter下实现低延迟的跨平台RTSP/RTMP播放
Android端如何实现拉取RTSP/RTMP流并回调YUV/RGB数据然后注入轻量级RTSP服务?
我们在对接开发Android平台音视频模块的时候,遇到过这样的问题,厂商希望拉取到海康、大华等摄像机的RTSP流,然后解码后的YUV或RGB数据回给他们,他们做视频分析或处理后,再投递给轻量级RTSP服务模块或RTMP推送模块,实现处理后的数据,二次转发,本文以拉取RTSP流,解析后再注入轻量级RTSP服务为例,介绍下大概的技术实现。
音视频牛哥
2023/09/21
1.4K0
Android端如何实现拉取RTSP/RTMP流并回调YUV/RGB数据然后注入轻量级RTSP服务?
Android平台实现无纸化同屏并推送RTMP或轻量级RTSP服务(毫秒级延迟)
在写这篇文章之前,实际上几年之前,我们就有非常稳定的无纸化同屏的模块,本文借demo更新,算是做个新的总结,废话不多说,先看图,本文以Android平台屏幕实时采集推送,Windows播放为例,和大家做个技术分享。
音视频牛哥
2024/03/10
4720
Android平台实现无纸化同屏并推送RTMP或轻量级RTSP服务(毫秒级延迟)
GB28181设备接入侧录像查询和录像下载技术探究之实时录像
我们在对接GB28181设备接入侧的时候,除了常规实时音视频按需上传外,还有个重要的功能,就是本地实时录像,录像后的数据,在执法记录仪等前端设备留底,然后,到工作站拷贝到专门的平台。
音视频牛哥
2023/07/16
7200
GB28181设备接入侧录像查询和录像下载技术探究之实时录像
Windows平台RTSP|RTMP播放器如何实现细粒度录像控制
好多开发者在跟我做技术交流的时候,说用大牛直播SDK模块的特点是,想到什么功能,找找头文件和demo几乎都有对应的实现,你们是何收集到这么多技术需求的?
音视频牛哥
2024/04/17
7200
Windows平台RTSP|RTMP播放器如何实现细粒度录像控制
如何在Android中实现低延迟的多实例RTSP|RTMP播放器
​在视频播放应用的开发中,如何有效地管理多个 RTSP|RTMP流实例是一个挑战。尤其是在 Android 上开发高性能、低延迟的多实例 RTSP|RTMP 播放器时,涉及到资源管理、线程同步和回调事件处理等多个层面的考虑。在本文中,我将展示如何使用大牛直播SDK,创建一个可支持多个实例的 RTSP 播放器,并分析如何在实际应用中进行优化。
音视频牛哥
2025/04/24
2280
如何在Android中实现低延迟的多实例RTSP|RTMP播放器
iOS平台如何实现毫秒级延迟的RTMP|RTSP播放器
在我的blog里面,最近很少有提到iOS平台RTMP推送|轻量级RTSP服务和RTMP|RTSP直播播放模块,实际上,我们在2016年就发布了iOS平台直播推拉流、转发模块,只是因为传统行业,对iOS的需求比较少,所以一直没单独说明,本文主要介绍下,如何在iOS平台播放RTMP或RTSP流。
音视频牛哥
2024/02/06
4020
iOS平台RTSP|RTMP直播播放器技术接入说明
大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以iOS平台为例,介绍下如何集成RTSP、RTMP播放模块。
音视频牛哥
2024/09/19
3290
iOS平台RTSP|RTMP直播播放器技术接入说明
Android平台不需要单独部署流媒体服务如何实现内网环境下一对一音视频互动
我们在做内网环境的一对一音视频互动的时候,遇到这样的技术诉求:如智能硬件场景下(比如操控智能硬件),纯内网环境,如何不要单独部署RTMP或类似流媒体服务,实现一对一音视频互动。
音视频牛哥
2023/05/17
3070
Android平台RTMP直播推送模块技术接入说明
大牛直播SDK跨平台RTMP直播推送模块,始于2015年,支持Windows、Linux(x64_64架构|aarch64)、Android、iOS平台,支持采集推送摄像头、屏幕、麦克风、扬声器、编码前、编码后数据对接,功能强大,性能优异,配合大牛直播SDK的SmartPlayer播放器,轻松实现毫秒级的延迟体验,满足大多数行业的使用场景。
音视频牛哥
2024/08/07
3750
Android平台RTMP直播推送模块技术接入说明
Unity3D下如何实现跨平台(Windows/Linux/Android/iOS)低延迟的RTMP、RTSP播放
好多开发者,希望我们能探讨下Unity平台RTMP或RTSP直播流数据播放和录制相关的模块,实际上,这块流程我们已经聊过多次,无非就是通过原生的RTMP或者RTSP模块,先从协议层拉取到数据,并解包解码,回调YUV或RGB数据,然后,在Unity创建响应的shader,获取图像数据填充纹理即可,说起来流程很简单,但是每个环节,如果做到极致体验,都非常难。简单来说,多一次拷贝,都会增大性能瓶颈或延迟。
音视频牛哥
2023/05/24
9790
Unity3D下如何实现跨平台(Windows/Linux/Android/iOS)低延迟的RTMP、RTSP播放
Unity下如何实现RTMP或RTSP流播放和录制
在探讨Unity平台RTMP或RTSP直播流数据播放和录制之前,我们先简单回顾下RTSP或RTMP直播流数据在Unity平台的播放流程:
音视频牛哥
2022/12/24
2.3K0
Unity下如何实现RTMP或RTSP流播放和录制
如何在Unity3d平台下低延迟播放RTMP或RTSP流
随着VR类、游戏类场景的快速发展,开发者对Unity3d低延迟的直播需求量越来越大,前两年,大牛直播SDK发布了Windows平台、Android平台和iOS平台的Unity3d RTMP和RTSP的播放,好多公司用起来体验都非常好,以下介绍大概实现流程。
音视频牛哥
2020/03/02
3.7K0
RTSP播放器或RTMP播放器常用Event事件回调设计
很多开发者在开发RTSP或RTMP播放器的时候,不晓得哪些event回调事件是有意义的,针对此,我们以大牛直播SDK(github)的Android平台RTSP/RTMP直播播放端为例,简单介绍下常用的event id,总的来说,有以下几个部分组成:
音视频牛哥
2020/10/15
1.1K0
推荐阅读
相关推荐
Android平台RTSP|RTMP播放器技术实践:基于大牛直播SDK的深度探索
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验