火山RTC 7 獲得遠端裸數據

一、獲得遠端裸數據

1、獲得h264數據

1)、遠端編碼后視頻數據監測器

/*** @locale zh* @type callback* @region 視頻管理* @brief 遠端編碼后視頻數據監測器<br>* 注意:回調函數是在 SDK 內部線程(非 UI 線程)同步拋出來的,請不要做耗時操作或直接操作 UI,否則可能導致 app 崩潰。*/
/*** @locale en* @type callback* @region  video management* @brief  Remote encoded video data monitor<br>* Note: Callback functions are thrown synchronously in a non-UI thread within the SDK. Therefore, you must not perform any time-consuming operations or direct UI operations within the callback function, as this may cause the app to crash.*/
class IRemoteEncodedVideoFrameObserver {
public:/*** @locale zh* @hidden constructor/destructor* @brief 析構函數*//*** @locale en* @hidden constructor/destructor* @brief  Destructor*/virtual ~IRemoteEncodedVideoFrameObserver() {}/*** @locale zh* @type callback* @region 視頻數據回調* @brief 調用 registerRemoteEncodedVideoFrameObserver{@link #IRTCVideo#registerRemoteEncodedVideoFrameObserver} 后,SDK 監測到遠端編碼后視頻數據時,觸發該回調* @param stream_info 收到的遠端流信息,參看 RemoteStreamKey{@link #RemoteStreamKey}* @param video_stream 收到的遠端視頻幀信息,參看 IEncodedVideoFrame{@link #IEncodedVideoFrame}*//*** @locale en* @type callback* @region  video data callback* @brief  Call registerRemoteEncodedVideoFrameObserver{@link #IRTCVideo#registerRemoteEncodedVideoFrameObserver}, the callback is triggered when the SDK detects the remote encoded video data* @param stream_info The received remote stream information. See RemoteStreamKey{@link #RemoteStreamKey}* @param video_stream The received remote video frame information. See IEncodedVideoFrame{@link #IEncodedVideoFrame}*/virtual void onRemoteEncodedVideoFrame(const RemoteStreamKey& stream_info, const IEncodedVideoFrame& video_stream) = 0;
};

2)、IRemoteEncodedVideoFrameObserver 派生


class ByteRTCEventHandler : public QObject,public bytertc::IRTCVideoEventHandler,public bytertc::IAudioEffectPlayerEventHandler,public bytertc::IMixedStreamObserver,public bytertc::IMediaPlayerEventHandler,public bytertc::IRemoteEncodedVideoFrameObserver,public bytertc::IVideoSink

 virtual void onRemoteEncodedVideoFrame(const bytertc::RemoteStreamKey& stream_info, const bytertc::IEncodedVideoFrame& video_stream) override;

void ByteRTCEventHandler::onRemoteEncodedVideoFrame(const bytertc::RemoteStreamKey& stream_info, const bytertc::IEncodedVideoFrame& video_stream) {}

std::unique_ptr<ByteRTCEventHandler> m_handler;

3)、registerRemoteEncodedVideoFrameObserver

/*** @locale zh* @type api* @region 視頻管理* @brief 注冊遠端編碼后視頻數據回調。  <br>*        完成注冊后,當 SDK 監測到遠端編碼后視頻幀時,會觸發 onRemoteEncodedVideoFrame{@link #IRemoteEncodedVideoFrameObserver#onRemoteEncodedVideoFrame} 回調* @param observer 遠端編碼后視頻數據監測器,參看 IRemoteEncodedVideoFrameObserver{@link #IRemoteEncodedVideoFrameObserver}* @return  *        + 0: 調用成功。<br>*        + < 0 : 調用失敗。查看 ReturnStatus{@link #ReturnStatus} 獲得更多錯誤說明* @note  *       + 更多自定義解碼功能說明參看 [自定義視頻編解碼](https://www.volcengine.com/docs/6348/82921#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%86%E9%A2%91%E8%A7%A3%E7%A0%81)。<br>*       + 該方法適用于手動訂閱,并且進房前后均可調用,建議在進房前調用。 <br>*       + 引擎銷毀前需取消注冊,調用該方法將參數設置為 nullptr 即可。*//*** @locale en* @type api* @region video management* @brief Video data callback after registering remote encoding.   <br>*         After registration, when the SDK detects a remote encoded video frame, it will trigger the onRemoteEncodedVideoFrame{@link #IRemoteEncodedVideoFrameObserver#onRemoteEncodedVideoFrame} callback* @param observer Remote encoded video data monitor. See IRemoteEncodedVideoFrameObserver{@link #IRemoteEncodedVideoFrameObserver}* @return  *        + 0: Success.<br>*        + < 0 : Fail. See ReturnStatus{@link #ReturnStatus} for more details* @note *        + See [Custom Video Encoding and Decoding](https://docs.byteplus.com/byteplus-rtc/docs/82921#custom-video-decoding) for more details about custom video decoding. <br>*        + This method applys to manual subscription mode and can be called either before or after entering the Room. It is recommended to call it before entering the room. <br>*        + The engine needs to be unregistered before it is destroyed. Call this method to set the parameter to nullptr.*/virtual int registerRemoteEncodedVideoFrameObserver(IRemoteEncodedVideoFrameObserver* observer) = 0;

m_video->registerRemoteEncodedVideoFrameObserver(m_handler.get());

2、自定義視頻渲染器

0)、IVideoSink?


/*** @locale zh* @type keytype* @brief 自定義視頻渲染器*/
/*** @locale en* @type keytype* @brief Custom video renderer*/
class IVideoSink {
public:/*** @locale zh* @type keytype* @brief 視頻幀編碼格式*//*** @locale en* @type keytype* @brief Video frame encoding format*/enum PixelFormat {/*** @locale zh* @brief YUV I420 格式*//*** @locale en* @brief YUV I420 format*/kI420 = VideoPixelFormat::kVideoPixelFormatI420,/*** @locale zh* @brief RGBA 格式, 字節序為 R8 G8 B8 A8*//*** @locale en* @brief RGBA format*/kRGBA = VideoPixelFormat::kVideoPixelFormatRGBA,/*** @locale zh* @brief 原始視頻幀格式*//*** @locale en* @brief Original format*/kOriginal = VideoPixelFormat::kVideoPixelFormatUnknown,};/*** @locale zh* @type callback* @brief 視頻幀回調* @param [out] video_frame 視頻幀結構類,參看 IVideoFrame{@link #IVideoFrame}* @return 返回值暫未使用*//*** @locale en* @type callback* @brief Video frame callback* @param [out] video_frame Video frame structure. See IVideoFrame{@link #IVideoFrame}.* @return Temporarily unavailable*/virtual bool onFrame(IVideoFrame* video_frame) = 0;/*** @locale zh* @type callback* @region 房間管理* @brief 獲取外部渲染耗時。* @note 獲取外部渲染耗時進行上報。開發者需要自己計算平均渲染耗時。*//*** @locale en* @type callback* @region Room Management* @brief Gets the time taken in custom rendering.* @note Gets the time taken in custom rendering and report. You need to calculate the average rendering time by yourself.*/virtual int getRenderElapse() = 0;/*** @locale zh* @type callback* @brief 釋放渲染器。* @note 通知開發者渲染器即將被廢棄。收到該返回通知后即可釋放資源。*//*** @locale en* @type callback* @brief Releases the renderer.* @note Used to notify the user that the renderer is about to be deprecated. Resources can be released upon receipt of this notification.*/virtual void release() {}/*** @locale zh* @hidden constructor/destructor* @brief 析構函數*//*** @locale en* @hidden constructor/destructor* @brief Destructor*/virtual ~IVideoSink() = default;/*** @locale zh* @hidden sink id* @brief sink id*//*** @locale en* @hidden sink id* @brief sink id*/virtual void* uniqueId() const { return (void *)this; }
};

1)、setRemoteVideoSink

    /*** @locale zh* @type api* @deprecated since 3.57, use setRemoteVideoRender{@link #IRTCVideo#setRemoteVideoRender} instead.* @region 自定義視頻采集渲染* @brief 將遠端視頻流與自定義渲染器綁定。* @param stream_key 遠端流信息,用于指定需要渲染的視頻流來源及屬性,參看 RemoteStreamKey{@link #RemoteStreamKey}。* @param video_sink 自定義視頻渲染器,參看 IVideoSink{@link #IVideoSink}。* @param required_format video_sink 適用的視頻幀編碼格式,參看 PixelFormat{@link #PixelFormat}。* @return  *        + 0: 調用成功。<br>*        + < 0 : 調用失敗。查看 ReturnStatus{@link #ReturnStatus} 獲得更多錯誤說明* @note  *        + RTC SDK 默認使用 RTC SDK 自帶的渲染器(內部渲染器)進行視頻渲染。<br>*        + 該方法進房前后均可以調用。若想在進房前調用,你需要在加入房間前獲取遠端流信息;若無法預先獲取遠端流信息,你可以在加入房間并通過 onUserPublishStream{@link #IRTCRoomEventHandler#onUserPublishStream} 回調獲取到遠端流信息之后,再調用該方法。<br>*        + 如果需要解除綁定,必須將 video_sink 設置為 null。退房時將清除綁定狀態。<br>*        + 本方法獲取的是后處理后的視頻幀,如需獲取其他位置的視頻幀(如解碼后的視頻幀),請調用 setRemoteVideoRender{@link #IRTCVideo#setRemoteVideoRender}。*//*** @locale en* @type api* @region Custom Video Capturing & Rendering* @brief Binds the remote video stream to a custom renderer.* @param stream_key Remote stream information which specifys the source and type of the video stream to be rendered. See RemoteStreamKey{@link #RemoteStreamKey}.* @param video_sink Custom video renderer. See IVideoSink{@link #IVideoSink}.* @param required_format Encoding format which applys to the custom renderer. See PixelFormat{@link #PixelFormat}.* @return  *        + 0: Success.<br>*        + < 0 : Fail. See ReturnStatus{@link #ReturnStatus} for more details* @note   *        + RTC SDK uses its own renderer (internal renderer) for video rendering by default.  <br>*        + Joining or leaving the room will not affect the binding state. <br>*         + This API can be called before and after entering the room. To call before entering the room, you need to get the remote stream information before joining the room; if you cannot get the remote stream information in advance, you can call the API after joining the room and getting the remote stream information via onUserPublishStream{@link #IRTCRoomEventHandler#onUserPublishStream}.<br>*         + If you need to unbind, you must set videoSink to null.*/virtual int setRemoteVideoSink(RemoteStreamKey stream_key, IVideoSink* video_sink, IVideoSink::PixelFormat required_format) = 0;

2)、遠端用戶發布流時,設置渲染方式

注意:設置registerRemoteEncodedVideoFrameObserver 后,setRemoteVideoSink 不再起作用了

//遠端用戶發流
void QuickStartWidget::onSigUserPublishStream(std::string roomid, std::string uid, bytertc::MediaStreamType type)
{QString log_str = QString("onUserPublishStream,roomid:")+ QString::fromStdString(roomid)+ ",uid:" + QString::fromStdString(uid)+ ",type:" + QString::number(type);appendCallback(log_str);if (!m_remote_rendered) {if (0) {bytertc::VideoCanvas cas;bytertc::RemoteStreamKey key;key.room_id = roomid.c_str();key.user_id = uid.c_str();key.stream_index = bytertc::kStreamIndexMain;cas.background_color = 0;cas.render_mode = bytertc::kRenderModeHidden;cas.view = nullptr;m_video->setRemoteVideoCanvas(key, cas);cas.view = (void*)ui->widget_remote->getWinId();m_video->setRemoteVideoCanvas(key, cas);ui->widget_remote->setUserInfo(roomid, uid);m_remote_rendered = true;}else {bytertc::RemoteStreamKey key;key.room_id = roomid.c_str();key.user_id = uid.c_str();key.stream_index = bytertc::kStreamIndexMain;//  m_video->setRemoteVideoSink(key, m_handler.get(), bytertc::IVideoSink::PixelFormat::kRGBA);m_video->setRemoteVideoSink(key, m_handler.get(), bytertc::IVideoSink::PixelFormat::kRGBA);m_remote_rendered = true;}}
}

3)、獲得遠端裸數據


bool ByteRTCEventHandler::onFrame(bytertc::IVideoFrame* video_frame) {bytertc::VideoFrameType type= video_frame->frameType();bytertc::VideoPixelFormat   format=video_frame->pixelFormat();bytertc::VideoContentType contentType= video_frame->videoContentType();int width = video_frame->width();int height= video_frame->height();bytertc::VideoRotation rotation = video_frame->rotation();bytertc::ColorSpace space = video_frame->colorSpace();int numPlans = video_frame->numberOfPlanes();uint8_t* data = video_frame->getPlaneData(numPlans-1);SaveRGBAToPNG(data, width, height, "output.png");return true;
}

測試

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"void SaveRGBAToPNG(uint8_t* rgbaData, int width, int height, const std::string& filePath) {// 第4個參數是每像素通道數,這里RGBA是4// 每行像素的跨度是 width * 4 字節stbi_write_png(filePath.c_str(), width, height, 4, rgbaData, width * 4);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82789.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82789.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82789.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

web 自動化之 Unittest 四大組件

文章目錄 一、如何開展自動化測試1、項目需求分析&#xff0c;了解業務需求 web 功能納入自動化測試2、選擇何種方式實現自動化測試 二、Unittest 框架三、TestCase 測試用例四、TestFixture 測試夾具 執行測試用例前的前置操作及后置操作五、TestSuite 測試套件 & TestLoa…

42、在.NET 中能夠將?靜態的?法覆寫成靜態?法嗎?

在.NET中&#xff0c;不能將非靜態方法&#xff08;實例方法&#xff09;直接覆寫&#xff08;Override&#xff09;為靜態方法&#xff08;Static Method&#xff09;。以下是關鍵原因和解釋&#xff1a; 1. 方法綁定的本質區別 實例方法&#xff1a;屬于對象的實例&#xf…

8天Python從入門到精通【itheima】-1~5

目錄 1節&#xff1a; 1.Python的優勢&#xff1a; 2.Python的獨具優勢的特點&#xff1a; 2節-初識Python&#xff1a; 1.Python的起源 2.Python廣泛的適用面&#xff1a; 3節-什么是編程語言&#xff1a; 1.編程語言的作用&#xff1a; 2.編程語言的好處&#xff1a;…

3D迷宮探險:偽3D渲染與運動控制的數學重構

目錄 3D迷宮探險:偽3D渲染與運動控制的數學重構引言第一章 偽3D渲染引擎1.1 射線投射原理1.2 紋理透視校正第二章 迷宮生成算法2.1 圖論生成模型2.2 復雜度控制第三章 第一人稱控制3.1 運動微分方程3.2 鼠標視角控制第四章 碰撞檢測優化4.1 層級檢測體系4.2 滑動響應算法第五章…

mac一鍵安裝gpt-sovit教程中,homebrew卡住不動的問題

mac一鍵安裝gpt-sovit教程 僅作為安裝過程中解決homebrew卡住問題的記錄 資源地址 https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/znoph9dtetg437xb#mlAoP 下載一鍵包 下載后并解壓&#xff0c;找到install for mac.sh&#xff0c;終端執行bash空格拖拽in…

git 遠程倉庫管理詳解

Git 的遠程倉庫管理是多人協作和代碼共享的核心功能。以下是 Git 遠程倉庫管理的詳細說明&#xff0c;包括常用操作、命令和最佳實踐。 1. 什么是遠程倉庫&#xff1f; 遠程倉庫&#xff08;Remote Repository&#xff09;&#xff1a;存儲在網絡服務器上的 Git 倉庫&#xff0…

【超詳細教程】安卓模擬器如何添加本地文件?音樂/照片/視頻一鍵導入!

作為一名安卓開發者或手游愛好者&#xff0c;安卓模擬器是我們日常工作和娛樂的重要工具。但很多新手在使用過程中常常遇到一個共同問題&#xff1a;**如何將電腦本地的音樂、照片、視頻等文件導入到安卓模擬器中&#xff1f;**今天&#xff0c;我將為大家帶來一份全網最詳細的…

使用vite重構vue-cli的vue3項目

一、修改依賴 首先修改 package.json&#xff0c;修改啟動方式與相應依賴 移除vue-cli并下載vite相關依賴&#xff0c;注意一些peerDependency如fast-glob需要手動下載 # 移除 vue-cli 相關依賴 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…

uniapp|實現手機通訊錄、首字母快捷導航功能、多端兼容(H5、微信小程序、APP)

基于uniapp實現帶首字母快捷導航的通訊錄功能,通過拼音轉換庫實現漢字姓名首字母提取與分類,結合uniapp的scroll-view組件與pageScrollTo API完成滾動定位交互,并引入uni-indexed-list插件優化索引欄性能。 目錄 核心功能實現動態索引欄生成?聯系人列表渲染?滾動定位聯動性…

C#中SetProperty方法使用

SetProperty 是 MVVM&#xff08;Model-View-ViewModel&#xff09; 模式中用于實現 屬性變更通知&#xff08;INotifyPropertyChanged&#xff09; 的核心方法&#xff0c;主要用于在屬性值變化時自動更新 UI 綁定。 1. SetProperty 的基本作用 更新字段值&#xff1a;修改屬性…

MYSQL 全量,增量備份與恢復

目錄 一 數據備份的重要性 1 數據備份的重要性 2 數據庫備份類型 2.1 從物理與邏輯的角度分類 2.2. 從數據庫的備份策略角度分類從數據庫的備份策略角度,數據庫的備份可分為完全備份、差異備份和增量備份。 3 常見的備份方法 3.1 物理冷備份 物理冷備份時需要在數據庫處…

豆瓣電影Top250數據工程實踐:從爬蟲到智能存儲的技術演進(含完整代碼)

目錄 引言:當豆瓣榜單遇見大數據技術 項目文檔 1.1 選題背景 1.2 項目目標 2. 項目概述 2.1 系統架構設計 2.2 技術選型 2.3 項目環境搭建 2.3.1 基礎環境準備 2.3.2 爬蟲環境配置 2.3.3 Docker安裝ES連接Kibana 安裝IK插件 2.3.4 vscode依賴服務安裝 3. 核心模…

深度 |國產操作系統“破繭而出”:鴻蒙電腦填補自主生態空白

真心為國內能有像華為這樣的技術型公司而自豪&#xff0c;一步步突圍技術封鎖。從這篇信息&#xff0c;可以給軟件從業者一個啟示&#xff1a;鴻蒙生態將是一個新的機會&#xff0c;值得好好把握。 鴻蒙電腦正成為中國電子信息技術新坐標。 超10億鴻蒙生態設備、2800家鴻蒙智…

【網絡安全】——大端序(Big-Endian)??和??小端序(Little-Endian)

字節序&#xff08;Endianness&#xff09;是計算機系統中多字節數據&#xff08;如整數、浮點數&#xff09;在內存中存儲或傳輸時&#xff0c;??字節排列順序??的規則。它分為兩種類型&#xff1a;??大端序&#xff08;Big-Endian&#xff09;??和??小端序&#xf…

六個倉庫合并為一個倉庫,保留master和develop分支的bat腳本

利用git subtree可以實現多個倉庫合并為一個倉庫&#xff0c;手動操作起來太麻煩了&#xff0c;今天花了點時間寫了一個可執行的腳本&#xff0c;現在操作起來就方便多了。 1、本地新建setup.bat文件 2、用編輯器打開&#xff08;我用的是Notepad&#xff09; 3、把下面代碼…

使用定時器監視當前PID 如果當前程序關閉 UI_Core.exe 也隨之自動關閉實現方法

使用定時器監視當前PID 如果當前程序關閉 UI_Core.exe 也隨之自動關閉實現方法 描述: C20 QT6.9 VS2022 中使用QProcess::startDetached(“UI_Core.exe”, QStringList(), QString(), &UI_Manage_pid);是啟動目標程序 能否同時告訴目標程序當前宿主程序的PID,在UI_CORE.EX…

神經網絡是如何工作的

人工智能最核心的技術之一&#xff0c;就是神經網絡&#xff08;Neural Networks&#xff09;。但很多初學者會覺得它是個黑盒&#xff1a;為什么神經網絡能識別圖片、翻譯語言&#xff0c;甚至生成文章&#xff1f; 本文用圖解最小代碼實現的方式&#xff0c;帶你深入理解&am…

LeetCode熱題100 兩數之和

目錄 兩數之和題目解析方法一暴力求解代碼 方法二哈希代碼 感謝各位大佬對我的支持,如果我的文章對你有用,歡迎點擊以下鏈接 &#x1f412;&#x1f412;&#x1f412; 個人主頁 &#x1f978;&#x1f978;&#x1f978; C語言 &#x1f43f;?&#x1f43f;?&#x1f43f;…

在線服務器具體是指什么?

在線服務器主要是指一種能夠隨時進行網絡連接、管理和操作的服務器&#xff0c;在線服務器是通過互聯網或者是本地網絡&#xff0c;來為企業和用戶提供數據存儲和網絡服務的&#xff0c;在線服務器也可以是物理服務器或者是虛擬服務器&#xff0c;能夠根據遠程訪問工具進行管理…

OSPF綜合性實驗

實驗拓撲&#xff1a; 第一步&#xff1a;進行子網劃分 172.16.0.0/17 172.16.0000 00 00.00000000 -- area1 172.16.0.1/22 -- AR1--G0/0/0 172.16.0.2/22 -- AR2--G0/0/0 172.16.0.3/22 -- AR3--G0/0/0 172.16.4.1/22 -- AR1-- Lo0 172.16.8.2/22 -- AR2-- Lo0 172.16.12.3/…