前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Android平台RTSP|RTMP直播播放器技术接入说明

Android平台RTSP|RTMP直播播放器技术接入说明

原创
作者头像
音视频牛哥
发布2025-03-02 21:49:00
发布2025-03-02 21:49:00
960
举报

​摘要

本文详细介绍了在 Android 平台上集成 RTSP 和 RTMP 直播播放模块的技术背景、系统要求、准备工作、接口设计、功能支持以及接口调用流程。通过合理的架构设计和优化,开发者可以高效地实现直播播放功能,满足不同场景下的应用需求。

一、技术背景

随着移动互联网的发展,实时视频传输在各个领域的应用越来越广泛。RTSP(Real Time Streaming Protocol)和 RTMP(Real-Time Messaging Protocol)作为主流的视频传输协议,广泛应用于直播、监控等领域。大牛直播 SDK 自 2015 年发布 RTSP 和 RTMP 直播播放模块以来,持续迭代优化,其 SmartPlayer 功能强大、性能强劲、稳定高效,得到了行业内的一致认可。

二、系统要求

  • 操作系统:支持 Android 5.1 及以上版本。
  • CPU 架构:支持 armv7、arm64、x86、x86_64。

三、准备工作

在集成 RTSP/RTMP 播放模块之前,需要完成以下准备工作:

1. 文件配置

  • SmartPlayerJniV2.java 文件放置在 com.daniulive.smartplayer 包名下(可在其他包名下调用)。
  • Smartavengine.jar 文件加入到工程中。
  • 拷贝 SmartPlayerV2\app\src\main\jniLibs 下的 armeabi-v7aarm64-v8ax86x86_64 目录下的 libSmartPlayer.so 文件到工程中。

2. 权限配置

AndroidManifest.xml 文件中添加以下权限:

代码语言:xml
复制
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

3. 库加载

在代码中加载相关动态链接库:

代码语言:xml
复制
static {
    System.loadLibrary("SmartPlayer");
}

4. 构建配置

build.gradle 文件中配置 32 位和 64 位库:

代码语言:xml
复制
splits {
    abi {
        enable true
        reset()
        include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        universalApk true
    }
}

5. 应用名称配置

如果需要集成到自己的系统进行测试,可以使用大牛直播 SDK 的 app name,授权版按照授权 app name 正常使用即可。修改 strings.xml 文件中的 app-name:

代码语言:xml
复制
<string name="app_name">SmartPlayerSDKDemo</string>

四、接口设计

1. 初始化接口

  • SmartPlayerOpen:初始化播放器,设置上下文信息,返回播放实例句柄。
  • SetSmartPlayerEventCallbackV2:设置事件回调接口,用于接收播放器的状态信息。

2. 解码设置接口

  • SetSmartPlayerVideoHWDecoder:设置是否使用 H.264 硬解码播放,如果硬解码不支持,自动适配到软解码。
  • SetSmartPlayerVideoHevcHWDecoder:设置是否使用 H.265 硬解码播放,如果硬解码不支持,自动适配到软解码。

3. 视频设置接口

  • SmartPlayerSetRenderScaleMode:设置视频画面的填充模式,如填充整个 view、等比例填充 view 等。
  • SmartPlayerSetSurfaceRenderFormat:设置 SurfaceView 模式下的 render 类型,如 RGB565 格式或 ARGB8888 格式。
  • SmartPlayerSetSurfaceAntiAlias:设置 SurfaceView 模式下的抗锯齿效果。

4. 播放控制接口

  • SmartPlayerSetSurface:设置播放的 surface,如果为 null,则播放纯音频。
  • SmartPlayerSetHWRenderMode:设置视频硬解码下的 Mediacodec 自行绘制模式。
  • SmartPlayerUpdateHWRenderSurface:更新硬解码 surface。
  • SmartPlayerSetExternalRender:提供解码后的 YUV/RGB 数据接口,供用户自行渲染或进一步处理。
  • SmartPlayerSetExternalAudioOutput:回调 audio 数据到上层,供二次处理之用。
  • SmartPlayerSetAudioOutputType:设置 audio 输出类型,如使用 audiotrack 模式等。

5. 模式设置接口

  • SmartPlayerSetBuffer:设置播放端缓存数据 buffer,单位为毫秒。
  • SmartPlayerSetFastStartup:设置快速启动,实现首屏秒开。
  • SmartPlayerSetLowLatencyMode:设置超低延迟播放模式,延迟可达到 200~400ms。
  • SmartPlayerSwitchPlaybackUrl:快速切换播放 URL,适用于不同数据流之间的快速切换。

6. RTSP 设置接口

  • SmartPlayerSetRTSPTcpMode:设置 RTSP TCP/UDP 模式。
  • SmartPlayerSetRTSPTimeout:设置 RTSP 超时时间,单位为秒。
  • SmartPlayerSetRTSPAutoSwitchTcpUdp:设置 RTSP TCP/UDP 自动切换。
  • SetRTSPAuthenticationInfo:设置 RTSP 用户名和密码。

7. 其他接口

  • SmartPlayerSetMute:实时静音。
  • SmartPlayerSetAudioVolume:实时调节播放音量,范围为 [0, 100]。
  • DisableEnhancedRTMP:禁用 Enhanced RTMP。
  • CaptureImage:支持 JPEG 和 PNG 格式的实时截图。
  • SmartPlayerSetRotation:设置视频镜像旋转,支持 0°、90°、180°、270° 旋转。
  • SmartPlayerSetFlipHorizontal:设置视频水平反转。
  • SmartPlayerSetFlipVertical:设置视频垂直反转。
  • SmartPlayerSetUrl:设置需要播放或录像的 RTMP/RTSP URL。
  • SmartPlayerStartPlay:开始播放 RTSP/RTMP 流。
  • SmartPlayerStopPlay:停止播放 RTSP/RTMP 流。
  • SmartPlayerClose:结束时调用 close 接口释放资源。

五、功能支持

  • 音频支持:AAC、Speex(RTMP)、PCMA、PCMU。
  • 视频支持:H.264、H.265。
  • 播放协议:RTSP、RTMP。
  • 播放模式:支持纯音频、纯视频、音视频播放。
  • 多实例播放:支持多实例播放。
  • 解码支持:支持软解码,特定机型硬解码。
  • RTSP 模式:支持 RTSP TCP、UDP 模式设置及自动切换。
  • 超时设置:支持 RTSP 超时时间设置,单位为秒。
  • 缓冲设置:支持 buffer 时间设置,单位为毫秒。
  • 低延迟模式:支持超低延迟模式。
  • 网络处理:支持断网自动重连、视频追赶,支持 buffer 状态等回调。
  • 视频操作:支持视频 view 实时旋转(0°、90°、180°、270°)、水平反转、垂直反转。
  • 绘制支持:支持 SurfaceView、OpenGL ES、TextureView 绘制。
  • 音频模式:支持 AudioTrack、OpenSL ES 模式。
  • 截图功能:支持 jpeg、png 实时截图。
  • 音量调节:支持实时音量调节。
  • 数据回调:支持解码前音视频数据回调、解码后 YUV/RGB 数据回调。
  • RTMP 增强:支持 Enhanced RTMP。
  • 录像功能:支持扩展录像功能。
  • 系统兼容:支持 Android 5.1 及以上版本。

六、接口调用详解

1. 初始化流程

onCreate() 方法中,首先创建 SmartPlayerJniV2 实例:

代码语言:java
复制
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_smart_player);
    libPlayer = new SmartPlayerJniV2();
    myContext = this.getApplicationContext();
}

2. 播放控制

实现开始播放和停止播放的功能,调用 InitAndSetConfig() 方法完成常规参数初始化,然后调用播放相关接口:

代码语言:java
复制
btnStartStopPlayback.setOnClickListener(new Button.OnClickListener() {
    public void onClick(View v) {
        if (isPlaying) {
            // 停止播放逻辑
        } else {
            // 开始播放逻辑
            if (!isRecording) {
                InitAndSetConfig();
            }
            libPlayer.SmartPlayerSetSurface(playerHandle, sSurfaceView);
            libPlayer.SmartPlayerSetRenderScaleMode(playerHandle, 1);
            if (isHardwareDecoder && is_enable_hardware_render_mode) {
                libPlayer.SmartPlayerSetHWRenderMode(playerHandle, 1);
            }
            libPlayer.SmartPlayerSetUserDataCallback(playerHandle, new UserDataCallback());
            libPlayer.SmartPlayerSetAudioOutputType(playerHandle, 1);
            if (isMute) {
                libPlayer.SmartPlayerSetMute(playerHandle, isMute ? 1 : 0);
            }
            if (isHardwareDecoder) {
                int isSupportHevcHwDecoder = libPlayer.SetSmartPlayerVideoHevcHWDecoder(playerHandle, 1);
                int isSupportH264HwDecoder = libPlayer.SetSmartPlayerVideoHWDecoder(playerHandle, 1);
                Log.i(TAG, "isSupportH264HwDecoder: " + isSupportH264HwDecoder + ", isSupportHevcHwDecoder: " + isSupportHevcHwDecoder);
            }
            libPlayer.SmartPlayerSetLowLatencyMode(playerHandle, isLowLatency ? 1 : 0);
            libPlayer.SmartPlayerSetFlipVertical(playerHandle, is_flip_vertical ? 1 : 0);
            libPlayer.SmartPlayerSetFlipHorizontal(playerHandle, is_flip_horizontal ? 1 : 0);
            libPlayer.SmartPlayerSetRotation(playerHandle, rotate_degrees);
            libPlayer.SmartPlayerSetAudioVolume(playerHandle, curAudioVolume);
            int iPlaybackRet = libPlayer.SmartPlayerStartPlay(playerHandle);
            if (iPlaybackRet != 0) {
                Log.e(TAG, "Call SmartPlayerStartPlay failed..");
                return;
            }
            // 更新 UI 和状态
        }
    }
});

3. 事件回调处理

实现事件回调接口,用于处理播放器的状态反馈,如网络状态、buffering 状态、录像状态、快照状态等:

代码语言:java
复制
class EventHandeV2 implements NTSmartEventCallbackV2 {
    @Override
    public void onNTSmartEventCallbackV2(long handle, int id, long param1, long param2, String param3, String param4, Object param5) {
        String player_event = "";
        switch (id) {
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
                player_event = "开始..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
                player_event = "连接中..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
                player_event = "连接失败..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
                player_event = "连接成功..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
                player_event = "连接断开..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
                player_event = "停止播放..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
                player_event = "分辨率信息: width: " + param1 + ", height: " + param2;
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
                player_event = "收不到媒体数据,可能是 url 错误..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_SWITCH_URL:
                player_event = "切换播放 URL..";
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CAPTURE_IMAGE:
                player_event = "快照: " + param1 + " 路径:" + param3;
                if (param1 == 0)
                    player_event = player_event + ", 截取快照成功";
                else
                    player_event = player_event + ", 截取快照失败";
                if (param4 != null && !param4.isEmpty())
                    player_event += (", user data:" + param4);
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RECORDER_START_NEW_FILE:
                player_event = "[record]开始一个新的录像文件 : " + param3;
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_ONE_RECORDER_FILE_FINISHED:
                player_event = "[record]已生成一个录像文件 : " + param3;
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_START_BUFFERING:
                Log.i(TAG, "Start Buffering");
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_BUFFERING:
                Log.i(TAG, "Buffering:" + param1 + "%");
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STOP_BUFFERING:
                Log.i(TAG, "Stop Buffering");
                break;
            case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_DOWNLOAD_SPEED:
                player_event = "download_speed:" + param1 + "Byte/s" + ", " + (param1 * 8 / 1000) + "kbps" + ", " + (param1 / 1024) + "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);
                player_event = "RTSP error code:" + param1;
                break;
        }
        if (player_event.length() > 0) {
            Log.i(TAG, player_event);
            Message message = new Message();
            message.what = PLAYER_EVENT_MSG;
            message.obj = player_event;
            handler.sendMessage(message);
        }
    }
}

4. 录像功能

如果需要对 RTSP/RTMP 流进行录像,可以调用以下接口:

代码语言:java
复制
btnStartStopRecorder.setOnClickListener(new Button.OnClickListener() {
    public void onClick(View v) {
        if (isRecording) {
            // 停止录像逻辑
        } else {
            // 开始录像逻辑
            if (!isPlaying) {
                InitAndSetConfig();
            }
            ConfigRecorderFunction();
            int startRet = libPlayer.SmartPlayerStartRecorder(playerHandle);
            if (startRet != 0) {
                Log.e(TAG, "Failed to start recorder.");
                return;
            }
            // 更新 UI 和状态
        }
    }
});

5. 实时截图

在播放过程中,可以调用以下接口进行实时截图:

代码语言:java
复制
btnCaptureImage.setOnClickListener(new Button.OnClickListener() {
    @SuppressLint("SimpleDateFormat")
    public void onClick(View v) {
        if (0 == playerHandle)
            return;
        if (null == capture_image_date_format_)
            capture_image_date_format_ = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS");
        String timestamp = capture_image_date_format_.format(new Date());
        String imageFileName = timestamp;
        String image_path = imageSavePath + "/" + imageFileName;
        int quality;
        boolean is_jpeg = true;
        if (is_jpeg) {
            image_path += ".jpeg";
            quality = 100;
        } else {
            image_path += ".png";
            quality = 100;
        }
        int capture_ret = libPlayer.CaptureImage(playerHandle, is_jpeg ? 0 : 1, quality, image_path, "test cix");
        Log.i(TAG, "capture image ret:" + capture_ret + ", file:" + image_path);
    }
});

6. 视频操作

对视频 view 进行水平、垂直翻转或旋转操作:

代码语言:java
复制
btnFlipVertical.setOnClickListener(new Button.OnClickListener() {
    public void onClick(View v) {
        is_flip_vertical = !is_flip_vertical;
        if (is_flip_vertical) {
            btnFlipVertical.setText("取消反转");
        } else {
            btnFlipVertical.setText("垂直反转");
        }
        if (playerHandle != 0) {
            libPlayer.SmartPlayerSetFlipVertical(playerHandle, is_flip_vertical ? 1 : 0);
        }
    }
});
btnFlipHorizontal.setOnClickListener(new Button.OnClickListener() {
    public void onClick(View v) {
        is_flip_horizontal = !is_flip_horizontal;
        if (is_flip_horizontal) {
            btnFlipHorizontal.setText("取消反转");
        } else {
            btnFlipHorizontal.setText("水平反转");
        }
        if (playerHandle != 0) {
            libPlayer.SmartPlayerSetFlipHorizontal(playerHandle, is_flip_horizontal ? 1 : 0);
        }
    }
});
btnRotation.setOnClickListener(new Button.OnClickListener() {
    public void onClick(View v) {
        rotate_degrees += 90;
        rotate_degrees = rotate_degrees % 360;
        if (0 == rotate_degrees) {
            btnRotation.setText("旋转90度");
        } else if (90 == rotate_degrees) {
            btnRotation.setText("旋转180度");
        } else if (180 == rotate_degrees) {
            btnRotation.setText("旋转270度");
        } else if (270 == rotate_degrees) {
            btnRotation.setText("不旋转");
        }
        if (playerHandle != 0) {
            libPlayer.SmartPlayerSetRotation(playerHandle, rotate_degrees);
        }
    }
});

7. 资源释放

onDestroy() 方法中,停止播放、录像,并释放播放器实例句柄:

代码语言:java
复制
@Override
protected void onDestroy() {
    Log.i(TAG, "Run into activity destory++");
    if (playerHandle != 0) {
        if (isPlaying) {
            libPlayer.SmartPlayerStopPlay(playerHandle);
        }
        if (isRecording) {
            libPlayer.SmartPlayerStopRecorder(playerHandle);
        }
        libPlayer.SmartPlayerClose(playerHandle);
        playerHandle = 0;
    }
    super.onDestroy();
    finish();
    System.exit(0);
}

七、总结

本文详细介绍了在 Android 平台上集成 RTSP 和 RTMP 直播播放模块的技术背景、系统要求、准备工作、接口设计、功能支持以及接口调用流程。通过合理的架构设计和优化,开发者可以高效地实现直播播放功能,满足不同场景下的应用需求。希望本文能为开发者提供有价值的参考,助力其实现更加稳定、高效的直播播放应用。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ​摘要
  • 一、技术背景
  • 二、系统要求
  • 三、准备工作
    • 1. 文件配置
    • 2. 权限配置
    • 3. 库加载
    • 4. 构建配置
    • 5. 应用名称配置
  • 四、接口设计
    • 1. 初始化接口
    • 2. 解码设置接口
    • 3. 视频设置接口
    • 4. 播放控制接口
    • 5. 模式设置接口
    • 6. RTSP 设置接口
    • 7. 其他接口
  • 五、功能支持
  • 六、接口调用详解
    • 1. 初始化流程
    • 2. 播放控制
    • 3. 事件回调处理
    • 4. 录像功能
    • 5. 实时截图
    • 6. 视频操作
    • 7. 资源释放
  • 七、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档