Android平台无纸化同屏如何实现实时录像功能

本文涉及的产品
视觉智能开放平台,图像通用资源包5000点
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,视频通用资源包5000点
简介: Android平台无纸化同屏,如果需要本地录像的话,实现难度不大,只要复用之前开发的录像模块的就可以,对我们来说,同屏采集这块,只是数据源不同而已,如果是自采集的其他数据,我们一样可以编码录像。

技术背景

我们在做无纸化同屏的时候,好多开发者采集到屏幕、麦克风|扬声器数据,除了需要推RTMP出去,或者启动个轻量级RTSP服务,对外提供个拉流的RTSP URL,别的终端过来拉流(小并发场景),还有个技术需求,就是需要本地实时录像。本文主要介绍屏幕采集的过程中,如何实现推送端录像。

技术实现

实际上,Android同屏,需要录像的话,和采集摄像头数据录像一样,只是数据源不同而已,鉴于不管什么格式的video数据,我们都是投递到模块底层做转换编码,所以本质上没啥差别。

image.gif

本地录像,我们界面上没有做展示,如果实现,很简单,就是加个开始录像|停止录像按钮即可。

对外提供了二次封装设计如下:

/*
 * NTStreamMediaEngine.java
 * Author: daniusdk.com
 * WeChat: xinsheng120
 *
 * Copyright © 2014~2024 DaniuSDK. All rights reserved.
 */
public interface NTStreamMediaEngine {
    void register_callback(Callback callback);
    void unregister_callback(Callback callback);
    void set_resolution_level(int level);
    int get_resolution_level();
    /*
    * 启动媒体投影
     */
    boolean start_video_capture(int token_code, android.content.Intent token_data);
    boolean is_video_capture_running();
    void stop_video_capture();
    /*
    * 启动麦克风
     */
    boolean start_audio_record(int sample_rate, int channels);
    boolean is_audio_record_running();
    void stop_audio_record();
    /*
     *  Android 10及以上支持, Android10以下设备调用直接返回false
     *  需要有RECORD_AUDIO权限
     *  要开启媒体投影
     */
    boolean start_audio_playback_capture(int sample_rate, int channels);
    boolean is_audio_playback_capture_running();
    void stop_audio_playback_capture();
    /*
     * 输出的音频类型
     *  0: 不输出音频
     *  1: 输出麦克风
     *  2: 输出audio playback(Android 10及以上支持)
     */
    boolean set_audio_output_type(int type);
    int get_audio_output_type();
    void set_fps(int fps);
    void set_gop(int gop);
    boolean set_video_encoder_type(int video_encoder_type);
    int get_video_encoder_type();
    ....
    /*
    * 启动本地录像
     */
    boolean start_stream_record(String record_directory, int file_max_size);
    boolean is_stream_recording();
    void stop_stream_record();
    boolean is_stream_running();
}

image.gif

开始录像实现如下:

/*
 * NTStreamMediaProjectionEngineImpl.java
 * Author: daniusdk.com
 * WeChat: xinsheng120
 *
 * Copyright © 2014~2024 DaniuSDK. All rights reserved.
 */
@Override
public boolean start_stream_record(String record_directory, int file_max_size) {
    if (stream_publisher_.is_recording()) {
        Log.e(TAG, "start_stream_record already recording");
        return false;
    }
    if (!is_video_capture_running()) {
        Log.e(TAG, "start_stream_record please start_video_capture first");
        return false;
    }
    if (is_null_or_empty(record_directory)) {
        Log.e(TAG, "start_stream_record record_directory is null");
        return false;
    }
    if (file_max_size < 5) {
        Log.e(TAG, "start_stream_record file_max_size:" + file_max_size + " error");
        return false;
    }
    Runnable r = new Runnable() {
        private String record_directory_;
        private int file_max_size_;
        @Override
        public void run() {
            if (!start_record_internal(this.record_directory_, this.file_max_size_)) {
                // notify .....
            }
        }
        Runnable set(String record_directory, int file_max_size) {
            this.record_directory_ = record_directory;
            this.file_max_size_ = file_max_size;
            return this;
        }
    }.set(record_directory, file_max_size);
    post_or_execute(r);
    Log.i(TAG, "start_stream_record record_directory:" + record_directory + ", file_max_size:" + file_max_size);
    return true;
}
@Override
public boolean is_stream_recording() {
    return stream_publisher_.is_recording();
}

image.gif

start_record_internal()实现如下:

private boolean start_record_internal(String record_directory, int file_max_size) {
    if (stream_publisher_.is_recording()) {
        Log.e(TAG, "start_record_internal already recording");
        return false;
    }
    if (!test_and_create_sdk_instance()) {
        Log.e(TAG, "start_record_internal create sdk instance failed");
        return false;
    }
    if (!config_record(record_directory, file_max_size)) {
        Log.e(TAG, "start_record_internal config_record failed");
        stream_publisher_.try_release();
        return false;
    }
    if (!stream_publisher_.StartRecorder()) {
        Log.e(TAG, "start_record_internal call sdk start failed");
        stream_publisher_.try_release();
        return false;
    }
    switch_audio_output_type(audio_output_type_);
    return true;
}

image.gif

这里调用的录像设置config_record()实现如下:

private boolean config_record(String record_directory, int file_max_size) {
    if (is_null_or_empty(record_directory))
        return false;
    if (file_max_size < 5)
        return false;
    if (null == this.lib_publisher_)
        return false;
    String directory = record_directory;
    int ret = lib_publisher_.SmartPublisherCreateFileDirectory(directory);
    if (ret != 0) {
        Log.e(TAG, "try create record directory failed, dir:" + directory);
        return  false;
    }
    if (!stream_publisher_.SetRecorderDirectory(directory)) {
        Log.e(TAG, "set record directory failed, dir:" + directory);
        return false;
    }
    if (!stream_publisher_.SetRecorderFileMaxSize(file_max_size)) {
        Log.e(TAG, "set record file max size failed, size:" + file_max_size);
        return false;
    }
    return true;
}

image.gif

停止录像:

@Override
public void stop_stream_record() {
    if (!stream_publisher_.is_recording())
        return;
    Runnable r = new Runnable() {
        @Override
        public void run() {
            stream_publisher_.StopRecorder();
            stream_publisher_.try_release();
            test_and_disable_post_audio();
        }
    };
    post_or_execute(r);
}

image.gif

总结

Android平台无纸化同屏,如果需要本地录像的话,实现难度不大,只要复用之前开发的录像模块的就可以,对我们来说,同屏采集这块,只是数据源不同而已,如果是自采集的其他数据,我们一样可以编码录像。以上是Android同屏录像设计,感兴趣的开发者,可以跟我单独沟通交流。

相关文章
|
4月前
|
监控 Android开发 数据安全/隐私保护
批量发送短信的平台,安卓群发短信工具插件脚本,批量群发短信软件【autojs版】
这个Auto.js脚本实现了完整的批量短信发送功能,包含联系人管理、短信内容编辑、发送状态监控等功能
|
7月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
8月前
|
存储 编解码 监控
Android平台GB28181执法记录仪技术方案与实现
本文介绍了大牛直播SDK的SmartGBD在执法记录仪场景中的应用。GB28181协议作为视频监控联网的国家标准,为设备互联互通提供规范。SmartGBD专为Android平台设计,支持音视频采集、编码与传输,具备自适应算法和多功能扩展优势。文章分析了执法记录仪的需求,如实时音视频传输、设备管理及数据安全,并详细阐述了基于SmartGBD的技术实现方案,包括环境准备、SDK集成、设备注册、音视频处理及功能扩展等步骤。最后展望了SmartGBD在未来智慧物联领域的广阔应用前景。
354 13
|
8月前
|
存储 编解码 开发工具
Android平台毫秒级低延迟HTTP-FLV直播播放器技术探究与实现
本文详细探讨了在Android平台上实现HTTP-FLV播放器的过程。首先介绍了FLV格式的基础,包括文件头和标签结构。接着分析了HTTP-FLV传输原理,通过分块传输实现流畅播放。然后重点讲解了播放器的实现步骤,涵盖网络请求、数据解析、音视频解码与渲染,以及播放控制功能的设计。文章还讨论了性能优化和网络异常处理的方法,并总结了HTTP-FLV播放器的技术价值,尤其是在特定场景下的应用意义。
324 11
|
8月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
11月前
|
IDE 开发工具 Android开发
移动应用开发之旅:探索Android和iOS平台
在这篇文章中,我们将深入探讨移动应用开发的两个主要平台——Android和iOS。我们将了解它们的操作系统、开发环境和工具,并通过代码示例展示如何在这两个平台上创建一个简单的“Hello World”应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧,帮助你更好地理解和掌握移动应用开发。
262 17
|
安全 Android开发 iOS开发
Android vs iOS:探索移动操作系统的设计与功能差异###
【10月更文挑战第20天】 本文深入分析了Android和iOS两个主流移动操作系统在设计哲学、用户体验、技术架构等方面的显著差异。通过对比,揭示了这两种系统各自的独特优势与局限性,并探讨了它们如何塑造了我们的数字生活方式。无论你是开发者还是普通用户,理解这些差异都有助于更好地选择和使用你的移动设备。 ###
461 3
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
424 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
17天前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
127 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
24天前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
205 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡

热门文章

最新文章