├── .gitignore ├── LICENSE ├── README.md ├── Readme.zh.md ├── one_to_one_video_gui ├── .cargo │ └── config.toml ├── Cargo.toml ├── README.md ├── Readme.zh.md ├── src │ └── main.rs └── ui │ └── form.ui ├── one_to_one_video_terminal ├── .cargo │ └── config.toml ├── Cargo.toml ├── README.md ├── Readme.zh.md └── src │ └── main.rs └── one_to_one_video_terminal_enhanced ├── .cargo └── config.toml ├── Cargo.toml ├── README.md ├── Readme.zh.md ├── copy_dlib ├── Cargo.toml └── src │ └── main.rs └── demo ├── .cargo └── config.toml ├── Cargo.toml └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | target/ 4 | *.lock 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Agora.io Community 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Agora Rust Quick-Start 2 | 3 | *[中文](Readme.zh.md) | English* 4 | 5 | Several demos are contained in this repository. You may pick up some demos to run! 6 | 7 | ## Index 8 | 9 | - [Agora Basic One-to-One Video Call Demo (Terminal Version)](https://github.com/AgoraIO-Community/Agora-Rust-QuickStart/tree/main/one_to_one_video_terminal) 10 | - [Agora Basic One-to-One Video Call Demo (Terminal Version with Dynamic Library Copy Program)](https://github.com/AgoraIO-Community/Agora-Rust-QuickStart/tree/main/one_to_one_video_terminal_enhanced) 11 | - [Agora Basic One-to-One Video Call Demo (GUI Version)](https://github.com/AgoraIO-Community/Agora-Rust-QuickStart/tree/main/one_to_one_video_gui) 12 | 13 | ## Prerequisites 14 | 15 | - rustc 16 | - cargo 17 | 18 | *If you are not familiar with Rust, please visit [Rust Programming Language](https://www.rust-lang.org/) for more infomation.* 19 | 20 | ## Quick-Start 21 | 22 | You can also write a simple demo yourself by the following instructins. 23 | 24 | 1. Open Terminal (macOS) or PowerShell (Windows) and create a new cargo project. 25 | 26 | ```bash 27 | $ cargo new first_agorartc_proj 28 | $ cd first_agorartc_proj 29 | ``` 30 | 31 | 2. Add a dependency to the `Cargo.toml`. 32 | 33 | ```rust 34 | [dependencies] 35 | agorartc-sys = "*" 36 | ``` 37 | 38 | 3. (macOS) Add a configuration to tell the compiler that `@rpath` is the loader path. 39 | 40 | ```bash 41 | $ mkdir .cargo 42 | $ touch .cargo/config.toml 43 | $ echo "[build]\nrustflags = [\"-C\", \"link-args=-Wl,-rpath,@loader_path\"]" > .cargo/config.toml 44 | ``` 45 | 46 | 4. Write a simple demo in `src/main.rs`. 47 | 48 | ```rust 49 | unsafe extern "C" fn on_error(error: ::std::os::raw::c_int, msg: *const ::std::os::raw::c_char) { 50 | let msg = CStr::from_ptr(msg); 51 | println!("On Error: code: {:?}, msg: {:?}", error, msg); 52 | } 53 | 54 | unsafe extern "C" fn on_warning(warn: ::std::os::raw::c_int, msg: *const ::std::os::raw::c_char) { 55 | if msg != std::ptr::null() { 56 | let msg = CStr::from_ptr(msg); 57 | println!("On Warn: code: {:?}, msg: {:?}", warn, msg); 58 | } 59 | println!("On Warning: code: {:?}", warn); 60 | } 61 | 62 | unsafe extern "C" fn on_join_channel( 63 | arg1: *const ::std::os::raw::c_char, 64 | uid: agorartc_sys::agorartc::agorartcnative::uid_t, 65 | elapsed: ::std::os::raw::c_int, 66 | ) { 67 | println!("onJoinChannel"); 68 | } 69 | 70 | unsafe extern "C" fn on_user_joined(uid: agorartc_sys::agorartc::agorartcnative::uid_t, elapsed: ::std::os::raw::c_int) { 71 | println!("onUserJoined"); 72 | } 73 | 74 | fn main() { 75 | let rtc_engine = &agorartc_sys::agorartc::Agora_Rtc_Engine; 76 | rtc_engine.add_event_handler(&mut agorartc_sys::agorartc::agorartcnative::RtcEventHandler { 77 | onJoinChannelSuccess: Some(on_join_channel), 78 | onReJoinChannelSuccess: None, 79 | onLeaveChannel: None, 80 | onConnectionLost: None, 81 | onConnectionInterrupted: None, 82 | onRequestToken: None, 83 | onUserJoined: Some(on_user_joined), 84 | onUserOffline: None, 85 | onAudioVolumeIndication: None, 86 | onUserMuteAudio: None, 87 | onWarning: Some(on_warning), 88 | onError: Some(on_error), 89 | onRtcStats: None, 90 | onAudioMixingFinished: None, 91 | onAudioRouteChanged: None, 92 | onFirstRemoteVideoDecoded: None, 93 | onVideoSizeChanged: None, 94 | onClientRoleChanged: None, 95 | onUserMuteVideo: None, 96 | onMicrophoneEnabled: None, 97 | onApiCallExecuted: None, 98 | onFirstLocalAudioFrame: None, 99 | onFirstRemoteAudioFrame: None, 100 | onLastmileQuality: None, 101 | onAudioQuality: None, 102 | onStreamInjectedStatus: None, 103 | onStreamUnpublished: None, 104 | onStreamPublished: None, 105 | onStreamMessageError: None, 106 | onStreamMessage: None, 107 | onConnectionBanned: None, 108 | onRemoteVideoTransportStats: None, 109 | onRemoteAudioTransportStats: None, 110 | onTranscodingUpdated: None, 111 | onAudioDeviceVolumeChanged: None, 112 | onActiveSpeaker: None, 113 | onMediaEngineStartCallSuccess: None, 114 | onMediaEngineLoadSuccess: None, 115 | onConnectionStateChanged: None, 116 | onRemoteSubscribeFallbackToAudioOnly: None, 117 | onLocalPublishFallbackToAudioOnly: None, 118 | onUserEnableLocalVideo: None, 119 | onRemoteVideoStateChanged: None, 120 | onVideoDeviceStateChanged: None, 121 | onAudioEffectFinished: None, 122 | onRemoteAudioMixingEnd: None, 123 | onRemoteAudioMixingBegin: None, 124 | onCameraExposureAreaChanged: None, 125 | onCameraFocusAreaChanged: None, 126 | onCameraReady: None, 127 | onAudioDeviceStateChanged: None, 128 | onUserEnableVideo: None, 129 | onFirstRemoteVideoFrame: None, 130 | onFirstLocalVideoFrame: None, 131 | onRemoteAudioStats: None, 132 | onRemoteVideoStats: None, 133 | onLocalVideoStats: None, 134 | onNetworkQuality: None, 135 | onTokenPrivilegeWillExpire: None, 136 | onVideoStopped: None, 137 | onAudioMixingStateChanged: None, 138 | onFirstRemoteAudioDecoded: None, 139 | onLocalVideoStateChanged: None, 140 | onNetworkTypeChanged: None, 141 | onRtmpStreamingStateChanged: None, 142 | onLastmileProbeResult: None, 143 | onLocalUserRegistered: None, 144 | onUserInfoUpdated: None, 145 | onLocalAudioStateChanged: None, 146 | onRemoteAudioStateChanged: None, 147 | onLocalAudioStats: None, 148 | onChannelMediaRelayStateChanged: None, 149 | onChannelMediaRelayEvent: None, 150 | onFacePositionChanged: None, 151 | onTestEnd: None, 152 | }); 153 | // If you do not have an App ID, see Appendix. 154 | rtc_engine.initialize("YOUR-APPID", agorartc_sys::agorartc::AREA_CODE::AREA_CODE_GLOBAL); 155 | rtc_engine.enable_video(); 156 | rtc_engine.join_channel("", "channel-name", "", 0u32); 157 | let mut input = String::new(); 158 | std::io::stdin().read_line(&mut input).expect("error: unable to read user input"); 159 | rtc_engine.leave_channel(); 160 | rtc_engine.release(true); 161 | } 162 | ``` 163 | 164 | 5. Add App ID. 165 | 166 | If you do not have an App ID, see Appendix. Please obtain an App ID without token. Replace `YOUR-APPID` in `rtc_engine.initialize("YOUR-APPID", agorartc_sys::agorartc::AREA_CODE::AREA_CODE_GLOBAL);` with your App ID. 167 | 168 | 6. Build your cargo project. 169 | 170 | ```bash 171 | $ cargo build 172 | ``` 173 | 174 | 7. Download the required SDK. 175 | 176 | - (macOS) Download SDK [Agora Video SDK for macOS](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Mac_v3_1_2_FULL.zip). Unzip the downloaded SDK package and copy the `AograRtcEngineKit.framework` from `libs` folder into `target/debug` folder. 177 | - (Windows) Download SDK [Agora Video SDK for Windows](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Windows_v3_1_2_FULL.zip). Unzip the downloaded SDK package and copy the `agora_rtc_sdk.dll` and `agora_rtc_sdk.lib` files from `libs/x86_64` into `target/debug` folder. 178 | 179 | 8. Run demo. 180 | 181 | ```bash 182 | $ cargo run 183 | ``` 184 | 185 | ## Appendix 186 | 187 | ### Create an Account and Obtain an App ID 188 | 189 | To use our SDK, you must obtain an app ID: 190 | 191 | 1. Create a developer account at [agora.io](https://dashboard.agora.io/signin/). Once you finish the sign-up process, you are redirected to the dashboard. 192 | 2. Navigate in the dashboard tree on the left to **Projects** > **Project List**. 193 | 3. Copy the app ID that you obtained from the dashboard into a text file. You will use it when you call our SDK. -------------------------------------------------------------------------------- /Readme.zh.md: -------------------------------------------------------------------------------- 1 | # Agora Rust 快速开始 2 | 3 | *[English](README.md) | 中文* 4 | 5 | 本仓库中包含一些代码示例。您可以选择一些示例进行运行体验。 6 | 7 | ## 索引 8 | 9 | - [Agora基础一对一视频通话示例(命令行版)](https://github.com/AgoraIO-Community/Agora-Rust-QuickStart/tree/main/one_to_one_video_terminal) 10 | - [Agora基础一对一视频通话示例(命令行版附加拷贝动态库脚本)](https://github.com/AgoraIO-Community/Agora-Rust-QuickStart/tree/main/one_to_one_video_terminal_enhanced) 11 | - [Agora基础一对一视频通话示例(图形化界面版)](https://github.com/AgoraIO-Community/Agora-Rust-QuickStart/tree/main/one_to_one_video_gui) 12 | 13 | ## 运行环境 14 | 15 | - rustc 16 | - cargo 17 | 18 | 若您第一次接触Rust语言,请访问[Rust官网](https://www.rust-lang.org/zh-CN/)以获取更多信息。 19 | 20 | ## 快速开始 21 | 22 | 您也可以根据如下教程完成一个简单的示例。 23 | 24 | 1. 打开终端(macOS)或PowerShell(Windows)并创建一个cargo项目。 25 | 26 | ```bash 27 | $ cargo new first_agorartc_proj 28 | $ cd first_agorartc_proj 29 | ``` 30 | 31 | 2. 在您项目的`Cargo.toml`中加入依赖项。 32 | 33 | ```rust 34 | [dependencies] 35 | agorartc-sys = "*" 36 | ``` 37 | 38 | 3. (macOS)添加一个配置让编译器在编译时将loader路径设置为`@rpath`。 39 | 40 | ```bash 41 | $ mkdir .cargo 42 | $ touch .cargo/config.toml 43 | $ echo "[build]\nrustflags = [\"-C\", \"link-args=-Wl,-rpath,@loader_path\"]" > .cargo/config.toml 44 | ``` 45 | 46 | 4. 在`src/main.rs`中写下一个简单的示例。 47 | 48 | ```rust 49 | unsafe extern "C" fn on_error(error: ::std::os::raw::c_int, msg: *const ::std::os::raw::c_char) { 50 | let msg = CStr::from_ptr(msg); 51 | println!("On Error: code: {:?}, msg: {:?}", error, msg); 52 | } 53 | 54 | unsafe extern "C" fn on_warning(warn: ::std::os::raw::c_int, msg: *const ::std::os::raw::c_char) { 55 | if msg != std::ptr::null() { 56 | let msg = CStr::from_ptr(msg); 57 | println!("On Warn: code: {:?}, msg: {:?}", warn, msg); 58 | } 59 | println!("On Warning: code: {:?}", warn); 60 | } 61 | 62 | unsafe extern "C" fn on_join_channel( 63 | arg1: *const ::std::os::raw::c_char, 64 | uid: agorartc_sys::agorartc::agorartcnative::uid_t, 65 | elapsed: ::std::os::raw::c_int, 66 | ) { 67 | println!("onJoinChannel"); 68 | } 69 | 70 | unsafe extern "C" fn on_user_joined(uid: agorartc_sys::agorartc::agorartcnative::uid_t, elapsed: ::std::os::raw::c_int) { 71 | println!("onUserJoined"); 72 | } 73 | 74 | fn main() { 75 | let rtc_engine = &agorartc_sys::agorartc::Agora_Rtc_Engine; 76 | rtc_engine.add_event_handler(&mut agorartc_sys::agorartc::agorartcnative::RtcEventHandler { 77 | onJoinChannelSuccess: Some(on_join_channel), 78 | onReJoinChannelSuccess: None, 79 | onLeaveChannel: None, 80 | onConnectionLost: None, 81 | onConnectionInterrupted: None, 82 | onRequestToken: None, 83 | onUserJoined: Some(on_user_joined), 84 | onUserOffline: None, 85 | onAudioVolumeIndication: None, 86 | onUserMuteAudio: None, 87 | onWarning: Some(on_warning), 88 | onError: Some(on_error), 89 | onRtcStats: None, 90 | onAudioMixingFinished: None, 91 | onAudioRouteChanged: None, 92 | onFirstRemoteVideoDecoded: None, 93 | onVideoSizeChanged: None, 94 | onClientRoleChanged: None, 95 | onUserMuteVideo: None, 96 | onMicrophoneEnabled: None, 97 | onApiCallExecuted: None, 98 | onFirstLocalAudioFrame: None, 99 | onFirstRemoteAudioFrame: None, 100 | onLastmileQuality: None, 101 | onAudioQuality: None, 102 | onStreamInjectedStatus: None, 103 | onStreamUnpublished: None, 104 | onStreamPublished: None, 105 | onStreamMessageError: None, 106 | onStreamMessage: None, 107 | onConnectionBanned: None, 108 | onRemoteVideoTransportStats: None, 109 | onRemoteAudioTransportStats: None, 110 | onTranscodingUpdated: None, 111 | onAudioDeviceVolumeChanged: None, 112 | onActiveSpeaker: None, 113 | onMediaEngineStartCallSuccess: None, 114 | onMediaEngineLoadSuccess: None, 115 | onConnectionStateChanged: None, 116 | onRemoteSubscribeFallbackToAudioOnly: None, 117 | onLocalPublishFallbackToAudioOnly: None, 118 | onUserEnableLocalVideo: None, 119 | onRemoteVideoStateChanged: None, 120 | onVideoDeviceStateChanged: None, 121 | onAudioEffectFinished: None, 122 | onRemoteAudioMixingEnd: None, 123 | onRemoteAudioMixingBegin: None, 124 | onCameraExposureAreaChanged: None, 125 | onCameraFocusAreaChanged: None, 126 | onCameraReady: None, 127 | onAudioDeviceStateChanged: None, 128 | onUserEnableVideo: None, 129 | onFirstRemoteVideoFrame: None, 130 | onFirstLocalVideoFrame: None, 131 | onRemoteAudioStats: None, 132 | onRemoteVideoStats: None, 133 | onLocalVideoStats: None, 134 | onNetworkQuality: None, 135 | onTokenPrivilegeWillExpire: None, 136 | onVideoStopped: None, 137 | onAudioMixingStateChanged: None, 138 | onFirstRemoteAudioDecoded: None, 139 | onLocalVideoStateChanged: None, 140 | onNetworkTypeChanged: None, 141 | onRtmpStreamingStateChanged: None, 142 | onLastmileProbeResult: None, 143 | onLocalUserRegistered: None, 144 | onUserInfoUpdated: None, 145 | onLocalAudioStateChanged: None, 146 | onRemoteAudioStateChanged: None, 147 | onLocalAudioStats: None, 148 | onChannelMediaRelayStateChanged: None, 149 | onChannelMediaRelayEvent: None, 150 | onFacePositionChanged: None, 151 | onTestEnd: None, 152 | }); 153 | // If you do not have an App ID, see Appendix. 154 | rtc_engine.initialize("YOUR-APPID", agorartc_sys::agorartc::AREA_CODE::AREA_CODE_GLOBAL); 155 | rtc_engine.enable_video(); 156 | rtc_engine.join_channel("", "channel-name", "", 0u32); 157 | let mut input = String::new(); 158 | std::io::stdin().read_line(&mut input).expect("error: unable to read user input"); 159 | rtc_engine.leave_channel(); 160 | rtc_engine.release(true); 161 | } 162 | ``` 163 | 164 | 5. 添加App ID。 165 | 166 | 如果您还未获取App ID,请参见附录。请获取一个没有token的App ID。将`rtc_engine.initialize("YOUR-APPID", agorartc_sys::agorartc::AREA_CODE::AREA_CODE_GLOBAL);`中`YOUR-APPID`替换为您的App ID。 167 | 168 | 6. 编译您的项目。 169 | 170 | ```bash 171 | $ cargo build 172 | ``` 173 | 174 | 7. 下载所需的SDK。 175 | 176 | - (macOS)在 [Agora Video SDK for macOS](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Mac_v3_1_2_FULL.zip) 下载 SDK。解压缩之后,将 `libs` 目录下的 `AograRtcEngineKit.framework` 复制到`target/debug`中。 177 | - (Windows)在 [Agora Video SDK for Windows](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Windows_v3_1_2_FULL.zip) 下载 SDK。解压缩之后,将 `libs/x86_64` 目录下的 `agora_rtc_sdk.dll` 和 `agora_rtc_sdk.lib` 复制到`target/debug`中。 178 | 179 | 8. 运行示例。 180 | 181 | ```bash 182 | $ cargo run 183 | ``` 184 | 185 | ## 附录 186 | 187 | ### 创建Agora账户并获取App ID 188 | 189 | 如果想要使用我们的SDK,您需要先获得一个App ID: 190 | 191 | 1. 在[agora.io](https://dashboard.agora.io/signin/)中注册一个账号。当您完成注册后,您将被链接至控制台。 192 | 2. 在控制台左侧点击**Projects** > **Project List**。 193 | 3. 请将您从控制台中获取的App ID保存,您将会在调用SDK时使用。 194 | -------------------------------------------------------------------------------- /one_to_one_video_gui/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = ["-C", "link-args=-Wl,-rpath,@loader_path"] -------------------------------------------------------------------------------- /one_to_one_video_gui/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "demo_gui_qt" 3 | version = "0.1.0" 4 | authors = ["DongYifan ", "Yiqing Huang "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | agorartc-sys = "*" 11 | qt_widgets = "*" 12 | qt_gui = "0.5.0" 13 | qt_core = "0.5.0" 14 | qt_ui_tools = "0.5.0" 15 | cpp_core = "0.6.0" 16 | -------------------------------------------------------------------------------- /one_to_one_video_gui/README.md: -------------------------------------------------------------------------------- 1 | # Agora Basic One-to-One Video Call Demo (GUI Version) 2 | 3 | *[中文](Readme.zh.md) | English* 4 | 5 | This is a Rust demo for Agora 1-to-1 video call with GUI. 6 | 7 | ### Requirements 8 | 9 | - Xcode (macOS) 10 | - Visual Studio 2017+ with C++ (Windows) 11 | - rustc 12 | - cargo 13 | 14 | If you are not familiar with Rust, please visit [Rust Programming Language](https://www.rust-lang.org/) for more infomation. 15 | 16 | ### Dependencies 17 | 18 | - agorartc-sys 19 | - qt_widgets 20 | - qt_gui 21 | - qt_core 22 | - qt_widget 23 | - qt_ui_tools 24 | - cpp_core 25 | 26 | ## Run Demo 27 | 28 | 1. Download and install Qt. 29 | 30 | For more information, please visit [Qt.io](https://www.qt.io/) and we also recommend you to take a glance at [Setting up for Rust Qt](https://rust-qt.github.io/qt/setting_up/). 31 | 32 | 2. Build demo. 33 | 34 | ```bash 35 | $ cargo build 36 | ``` 37 | 38 | 3. Download the required SDK. 39 | 40 | - (macOS) Download SDK [Agora Video SDK for macOS](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Mac_v3_1_2_FULL.zip). Unzip the downloaded SDK package and copy the `AograRtcEngineKit.framework` from `libs` folder into `target/debug` folder. 41 | - (Windows) Download SDK [Agora Video SDK for Windows](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Windows_v3_1_2_FULL.zip). Unzip the downloaded SDK package and copy the `agora_rtc_sdk.dll` and `agora_rtc_sdk.lib` files from `libs/x86_64` into `target/debug` folder. 42 | 43 | 4. (macOS) Change the `@rpath` link to Qt related dynamic lib to the correct path. 44 | 45 | Find your absolute path to QtGui, QtWidgets and QtCore. Run the following instructions: 46 | 47 | ```bash 48 | $ cd target/debug 49 | $ install_name_tool -change @rpath/libQt5Gui.5.dylib [your-path-to]/lib/QtGui.framework/QtGui demo_gui_qt 50 | $ install_name_tool -change @rpath/libQt5Widgets.5.dylib [your-path-to]/lib/QtWidgets.framework/QtWidgets demo_gui_qt 51 | $ install_name_tool -change @rpath/libQt5Core.5.dylib [your-path-to]/lib/QtCore.framework/QtCore demo_gui_qt 52 | ``` 53 | 54 | For example: 55 | 56 | ```bash 57 | $ cd target/debug 58 | $ install_name_tool -change @rpath/libQt5Gui.5.dylib ~/Qt/5.15.1/clang_64/lib/QtGui.framework/QtGui demo_gui_qt 59 | $ install_name_tool -change @rpath/libQt5Widgets.5.dylib ~/Qt/5.15.1/clang_64/lib/QtWidgets.framework/QtWidgets demo_gui_qt 60 | $ install_name_tool -change @rpath/libQt5Core.5.dylib ~/Qt/5.15.1/clang_64/lib/QtCore.framework/QtCore demo_gui_qt 61 | ``` 62 | 63 | If you follow the instructions above but it still tells `Reason: image not found`, please change the path of `demo_gui_qt` in `target/debug/deps` using the same method. 64 | 65 | For example: 66 | 67 | ```bash 68 | $ cd target/debug/deps 69 | $ install_name_tool -change @rpath/libQt5Gui.5.dylib ~/Qt/5.15.1/clang_64/lib/QtGui.framework/QtGui demo_gui_qt 70 | $ install_name_tool -change @rpath/libQt5Widgets.5.dylib ~/Qt/5.15.1/clang_64/lib/QtWidgets.framework/QtWidgets demo_gui_qt 71 | $ install_name_tool -change @rpath/libQt5Core.5.dylib ~/Qt/5.15.1/clang_64/lib/QtCore.framework/QtCore demo_gui_qt 72 | ``` 73 | 74 | 5. Run demo. 75 | 76 | For Windows users, please run the following instruction in the **VS command prompt**. 77 | 78 | ```rust 79 | $ cargo run 80 | ``` 81 | 82 | ## Appendix 83 | 84 | ### Create an Account and Obtain an App ID 85 | 86 | To use our SDK, you must obtain an app ID: 87 | 88 | 1. Create a developer account at [agora.io](https://dashboard.agora.io/signin/). Once you finish the sign-up process, you are redirected to the dashboard. 89 | 2. Navigate in the dashboard tree on the left to **Projects** > **Project List**. 90 | 3. Copy the app ID that you obtained from the dashboard into a text file. You will use it when you run demo (there is an input box in our GUI demo). -------------------------------------------------------------------------------- /one_to_one_video_gui/Readme.zh.md: -------------------------------------------------------------------------------- 1 | # Agora基础一对一视频通话示例(图形化界面版) 2 | 3 | *[English](README.md) | 中文* 4 | 5 | 6 | 7 | ### 运行环境 8 | 9 | - Xcode (macOS) 10 | - Visual Studio 2017+ with C++ (Windows) 11 | - rustc 12 | - cargo 13 | 14 | 若您第一次接触Rust语言,请访问[Rust官网](https://www.rust-lang.org/zh-CN/)以获取更多信息。 15 | 16 | ### 依赖包 17 | 18 | - agorartc-sys 19 | - qt_widgets 20 | - qt_gui 21 | - qt_core 22 | - qt_widget 23 | - qt_ui_tools 24 | - cpp_core 25 | 26 | ## 运行示例 27 | 28 | 1. 下载并安装Qt。 29 | 30 | 详情请参考[Qt官网](https://www.qt.io/cn)。推荐您同时阅读[Setting up for Rust Qt](https://rust-qt.github.io/qt/setting_up/)以获得一些帮助。 31 | 32 | 2. 编译示例 33 | 34 | ```bash 35 | $ cargo build 36 | ``` 37 | 38 | 3. 下载所需的SDK。 39 | 40 | - (macOS)在 [Agora Video SDK for macOS](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Mac_v3_1_2_FULL.zip) 下载 SDK。解压缩之后,将 `libs` 目录下的 `AograRtcEngineKit.framework` 复制到`target/debug`中。 41 | - (Windows)在 [Agora Video SDK for Windows](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Windows_v3_1_2_FULL.zip) 下载 SDK。解压缩之后,将 `libs/x86_64` 目录下的 `agora_rtc_sdk.dll` 和 `agora_rtc_sdk.lib` 复制到`target/debug`中。 42 | 43 | 4. (macOS)将链接到Qt的`@rpath`替换成正确的绝对路径。 44 | 45 | 找到QtGui、QtWidgets和QtCore的正确位置和路径。输入以下命令: 46 | 47 | ```bash 48 | $ cd target/debug 49 | $ install_name_tool -change @rpath/libQt5Gui.5.dylib [your-path-to]/lib/QtGui.framework/QtGui demo_gui_qt 50 | $ install_name_tool -change @rpath/libQt5Widgets.5.dylib [your-path-to]/lib/QtWidgets.framework/QtWidgets demo_gui_qt 51 | $ install_name_tool -change @rpath/libQt5Core.5.dylib [your-path-to]/lib/QtCore.framework/QtCore demo_gui_qt 52 | ``` 53 | 54 | 例如: 55 | 56 | ```bash 57 | $ cd target/debug 58 | $ install_name_tool -change @rpath/libQt5Gui.5.dylib ~/Qt/5.15.1/clang_64/lib/QtGui.framework/QtGui demo_gui_qt 59 | $ install_name_tool -change @rpath/libQt5Widgets.5.dylib ~/Qt/5.15.1/clang_64/lib/QtWidgets.framework/QtWidgets demo_gui_qt 60 | $ install_name_tool -change @rpath/libQt5Core.5.dylib ~/Qt/5.15.1/clang_64/lib/QtCore.framework/QtCore demo_gui_qt 61 | ``` 62 | 63 | 若依旧显示`Reason: image not found`,请将`target/debug/deps`中的`demo_gui_qt`也按照上述办法替换路径。 64 | 65 | 例如: 66 | 67 | ```bash 68 | $ cd target/debug/deps 69 | $ install_name_tool -change @rpath/libQt5Gui.5.dylib ~/Qt/5.15.1/clang_64/lib/QtGui.framework/QtGui demo_gui_qt 70 | $ install_name_tool -change @rpath/libQt5Widgets.5.dylib ~/Qt/5.15.1/clang_64/lib/QtWidgets.framework/QtWidgets demo_gui_qt 71 | $ install_name_tool -change @rpath/libQt5Core.5.dylib ~/Qt/5.15.1/clang_64/lib/QtCore.framework/QtCore demo_gui_qt 72 | ``` 73 | 74 | 5. 运行示例。 75 | 76 | Windows用户需要在**VS command prompt**中运行以下命令。 77 | 78 | ```bash 79 | $ cargo run 80 | ``` 81 | 82 | ## 附录 83 | 84 | ### 创建Agora账户并获取App ID 85 | 86 | 如果想要使用我们的SDK,您需要先获得一个App ID: 87 | 88 | 1. 在[agora.io](https://dashboard.agora.io/signin/)中注册一个账号。当您完成注册后,您将被链接至控制台。 89 | 2. 在控制台左侧点击**Projects** > **Project List**。 90 | 3. 请将您从控制台中获取的App ID保存,您将会在运行示例时使用(示例图形化界面中有输入框)。 -------------------------------------------------------------------------------- /one_to_one_video_gui/src/main.rs: -------------------------------------------------------------------------------- 1 | // 2 | // one_to_one_video_gui 3 | // Agora-Rust-Video-Tutorial 4 | // 5 | // Created by Yiqing Huang on 2020/11/20. 6 | // Copyright © 2020 Agora. All rights reserved. 7 | // 8 | 9 | #![allow(non_upper_case_globals)] 10 | #![allow(non_snake_case)] 11 | #![allow(non_camel_case_types)] 12 | #![allow(dead_code)] 13 | #![allow(unused_variables)] 14 | 15 | use std::ffi::CStr; 16 | 17 | use qt_widgets::*; 18 | use qt_core::*; 19 | use cpp_core::{Ptr, StaticUpcast}; 20 | use std::rc::Rc; 21 | use qt_ui_tools::ui_form; 22 | 23 | static mut local_win_id: std::os::raw::c_ulonglong = 0; 24 | static mut remote_win_id: std::os::raw::c_ulonglong = 0; 25 | static rtc_engine: &agorartc_sys::agorartc::Agora_Rtc_Engine = &agorartc_sys::agorartc::Agora_Rtc_Engine; 26 | 27 | unsafe extern "C" fn on_api_call_executed( 28 | err: ::std::os::raw::c_int, 29 | api: *const ::std::os::raw::c_char, 30 | result: *const ::std::os::raw::c_char, 31 | ) { 32 | let api_ = CStr::from_ptr(api); 33 | let result_ = CStr::from_ptr(result); 34 | println!("API Excuted: err {:?}, api {:?}, result {:?}", err, api_, result_); 35 | } 36 | 37 | unsafe extern "C" fn on_error(error: ::std::os::raw::c_int, msg: *const ::std::os::raw::c_char) { 38 | let msg = CStr::from_ptr(msg); 39 | println!("On Error: code: {:?}, msg: {:?}", error, msg); 40 | } 41 | 42 | unsafe extern "C" fn on_warning(warn: ::std::os::raw::c_int, msg: *const ::std::os::raw::c_char) { 43 | if msg != std::ptr::null() { 44 | let msg = CStr::from_ptr(msg); 45 | println!("On Warn: code: {:?}, msg: {:?}", warn, msg); 46 | } 47 | println!("On Warning: code: {:?}", warn); 48 | } 49 | 50 | unsafe extern "C" fn on_join_channel( 51 | arg1: *const ::std::os::raw::c_char, 52 | uid: agorartc_sys::agorartc::agorartcnative::uid_t, 53 | elapsed: ::std::os::raw::c_int, 54 | ) { 55 | println!("on_join_channel >>>>>>>>>>> {:?}", local_win_id); 56 | let channle_id: [::std::os::raw::c_char; 65usize] = [0; 65usize]; 57 | rtc_engine.setup_local_video(agorartc_sys::agorartc::agorartcnative::VideoCanvas { 58 | view: local_win_id as *mut std::ffi::c_void, 59 | renderMode: 1, 60 | channelId: channle_id, 61 | uid: 0, 62 | priv_: std::ptr::null_mut(), 63 | mirrorMode: 0, 64 | }); 65 | 66 | rtc_engine.start_preview(); 67 | } 68 | 69 | unsafe extern "C" fn on_user_joined(uid: agorartc_sys::agorartc::agorartcnative::uid_t, elapsed: ::std::os::raw::c_int) { 70 | let channle_id: [::std::os::raw::c_char; 65usize] = [0; 65usize]; 71 | rtc_engine.setup_remote_video(agorartc_sys::agorartc::agorartcnative::VideoCanvas { 72 | view: remote_win_id as *mut std::ffi::c_void, 73 | renderMode: 1, 74 | channelId: channle_id, 75 | uid: uid, 76 | priv_: std::ptr::null_mut(), 77 | mirrorMode: 0, 78 | }); 79 | } 80 | 81 | #[ui_form("../ui/form.ui")] 82 | #[derive(Debug)] 83 | struct Form { 84 | widget: QBox, 85 | joinButton: QPtr, 86 | leaveButton: QPtr, 87 | gridLayout_2: QPtr, 88 | remote_window: QPtr, 89 | local_window: QPtr, 90 | appIdEdit: QPtr, 91 | channelEdit: QPtr, 92 | } 93 | 94 | #[derive(Debug)] 95 | struct main_window { 96 | form: Form, 97 | } 98 | 99 | impl StaticUpcast for main_window { 100 | unsafe fn static_upcast(ptr: Ptr) -> Ptr { 101 | ptr.form.widget.as_ptr().static_upcast() 102 | } 103 | } 104 | 105 | impl main_window { 106 | fn new() -> Rc { 107 | unsafe { 108 | let this = Rc::new(main_window { 109 | form: Form::load(), 110 | }); 111 | this.init(); 112 | this 113 | } 114 | } 115 | 116 | unsafe fn init(self: &Rc) { 117 | self.form.remote_window.set_attribute_2a(WidgetAttribute::WANativeWindow, true); 118 | self.form.joinButton.clicked().connect(&self.slot_on_join_button_clicked()); 119 | self.form.leaveButton.clicked().connect(&self.slot_on_leave_button_clicked()); 120 | } 121 | 122 | fn check_app_id(self: &Rc, app_id: String) -> bool { 123 | if app_id.len() == 0 { 124 | return false; 125 | } 126 | true 127 | } 128 | 129 | fn check_channel_name(self: &Rc, channel_name: String) -> bool { 130 | let channel_name_slice = channel_name.as_bytes(); 131 | for channel_name_char in channel_name_slice.iter() { 132 | let n = *channel_name_char; 133 | if n >= 97 && n <= 122 {} else if n >= 65 && n <= 90 {} else if n >= 48 && n <= 57 {} else if n == 32 || n == 33 || n == 36 || n == 37 || n == 38 || n == 40 || n == 43 || 134 | n == 45 || n == 58 || n == 59 || n == 60 || n == 61 || n == 46 || n == 62 || 135 | n == 63 || n == 64 || n == 91 || n == 93 || n == 94 || n == 95 || n == 123 || 136 | n == 125 || n == 124 || n == 126 {} else { 137 | return false; 138 | } 139 | } 140 | true 141 | } 142 | 143 | #[slot(SlotNoArgs)] 144 | unsafe fn on_join_button_clicked(self: &Rc) { 145 | local_win_id = self.form.local_window.effective_win_id(); 146 | remote_win_id = self.form.remote_window.effective_win_id(); 147 | let app_id = CStr::from_ptr((*(*self.form.appIdEdit.text().as_ptr()).to_local8_bit().as_ptr()).data()).to_string_lossy().into_owned(); 148 | let channel_name = CStr::from_ptr((*(*self.form.channelEdit.text().as_ptr()).to_local8_bit().as_ptr()).data()).to_string_lossy().into_owned(); 149 | let msg = QMessageBox::new(); 150 | msg.set_text(&qs("Message")); 151 | if self.check_app_id(app_id.clone()) == false { 152 | msg.set_informative_text(&qs("Please input your App ID of your project.")); 153 | msg.exec(); 154 | return; 155 | } 156 | if channel_name.len() == 0 { 157 | msg.set_informative_text(&qs("Please input the channel name.")); 158 | msg.exec(); 159 | return; 160 | } 161 | if channel_name.len() > 64 { 162 | msg.set_informative_text(&qs("The length of the channel name must be less than 64.")); 163 | msg.exec(); 164 | return; 165 | } 166 | if self.check_channel_name(channel_name.clone()) == false { 167 | return; 168 | } 169 | 170 | let mut handler = agorartc_sys::agorartc::agorartcnative::RtcEventHandler { 171 | onJoinChannelSuccess: Some(on_join_channel), 172 | onReJoinChannelSuccess: None, 173 | onLeaveChannel: None, 174 | onConnectionLost: None, 175 | onConnectionInterrupted: None, 176 | onRequestToken: None, 177 | onUserJoined: Some(on_user_joined), 178 | onUserOffline: None, 179 | onAudioVolumeIndication: None, 180 | onUserMuteAudio: None, 181 | onWarning: Some(on_warning), 182 | onError: Some(on_error), 183 | onRtcStats: None, 184 | onAudioMixingFinished: None, 185 | onAudioRouteChanged: None, 186 | onFirstRemoteVideoDecoded: None, 187 | onVideoSizeChanged: None, 188 | onClientRoleChanged: None, 189 | onUserMuteVideo: None, 190 | onMicrophoneEnabled: None, 191 | onApiCallExecuted: Some(on_api_call_executed), 192 | onFirstLocalAudioFrame: None, 193 | onFirstRemoteAudioFrame: None, 194 | onLastmileQuality: None, 195 | onAudioQuality: None, 196 | onStreamInjectedStatus: None, 197 | onStreamUnpublished: None, 198 | onStreamPublished: None, 199 | onStreamMessageError: None, 200 | onStreamMessage: None, 201 | onConnectionBanned: None, 202 | onRemoteVideoTransportStats: None, 203 | onRemoteAudioTransportStats: None, 204 | onTranscodingUpdated: None, 205 | onAudioDeviceVolumeChanged: None, 206 | onActiveSpeaker: None, 207 | onMediaEngineStartCallSuccess: None, 208 | onMediaEngineLoadSuccess: None, 209 | onConnectionStateChanged: None, 210 | onRemoteSubscribeFallbackToAudioOnly: None, 211 | onLocalPublishFallbackToAudioOnly: None, 212 | onUserEnableLocalVideo: None, 213 | onRemoteVideoStateChanged: None, 214 | onVideoDeviceStateChanged: None, 215 | onAudioEffectFinished: None, 216 | onRemoteAudioMixingEnd: None, 217 | onRemoteAudioMixingBegin: None, 218 | onCameraExposureAreaChanged: None, 219 | onCameraFocusAreaChanged: None, 220 | onCameraReady: None, 221 | onAudioDeviceStateChanged: None, 222 | onUserEnableVideo: None, 223 | onFirstRemoteVideoFrame: None, 224 | onFirstLocalVideoFrame: None, 225 | onRemoteAudioStats: None, 226 | onRemoteVideoStats: None, 227 | onLocalVideoStats: None, 228 | onNetworkQuality: None, 229 | onTokenPrivilegeWillExpire: None, 230 | onVideoStopped: None, 231 | onAudioMixingStateChanged: None, 232 | onFirstRemoteAudioDecoded: None, 233 | onLocalVideoStateChanged: None, 234 | onNetworkTypeChanged: None, 235 | onRtmpStreamingStateChanged: None, 236 | onLastmileProbeResult: None, 237 | onLocalUserRegistered: None, 238 | onUserInfoUpdated: None, 239 | onLocalAudioStateChanged: None, 240 | onRemoteAudioStateChanged: None, 241 | onLocalAudioStats: None, 242 | onChannelMediaRelayStateChanged: None, 243 | onChannelMediaRelayEvent: None, 244 | onFacePositionChanged: None, 245 | onTestEnd: None, 246 | }; 247 | println!("begin 2"); 248 | rtc_engine.add_event_handler(&mut handler as *mut _); 249 | rtc_engine.initialize(&app_id, agorartc_sys::agorartc::AREA_CODE::AREA_CODE_GLOBAL); 250 | rtc_engine.enable_video(); 251 | rtc_engine.join_channel("", &channel_name, "", 0u32); 252 | } 253 | 254 | #[slot(SlotNoArgs)] 255 | unsafe fn on_leave_button_clicked(self: &Rc) { 256 | rtc_engine.leave_channel(); 257 | } 258 | 259 | #[slot(SlotNoArgs)] 260 | unsafe fn on_list_selection_changed(self: &Rc) {} 261 | 262 | #[slot(SlotNoArgs)] 263 | unsafe fn on_filter_changed(self: &Rc) {} 264 | 265 | #[slot(SlotNoArgs)] 266 | unsafe fn on_remove_selected_clicked(self: &Rc) {} 267 | 268 | #[slot(SlotNoArgs)] 269 | unsafe fn on_remove_completed_clicked(self: &Rc) {} 270 | 271 | fn show(self: &Rc) { 272 | unsafe { 273 | self.form.widget.show(); 274 | } 275 | } 276 | } 277 | 278 | fn main() { 279 | QApplication::init(|_| { 280 | let todo_widget = main_window::new(); 281 | todo_widget.show(); 282 | unsafe { QApplication::exec() } 283 | }) 284 | } -------------------------------------------------------------------------------- /one_to_one_video_gui/ui/form.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 486 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 540 21 | 130 22 | 231 23 | 31 24 | 25 | 26 | 27 | 28 | 微软雅黑 Light 29 | 30 | 31 | 32 | ArrowCursor 33 | 34 | 35 | 36 | 37 | 38 | 540 39 | 110 40 | 111 41 | 16 42 | 43 | 44 | 45 | 46 | Arial 47 | 48 | 49 | 50 | Channel Name: 51 | 52 | 53 | 54 | 55 | 56 | 550 57 | 180 58 | 93 59 | 28 60 | 61 | 62 | 63 | 64 | Arial 65 | 66 | 67 | 68 | join 69 | 70 | 71 | 72 | 73 | 74 | 660 75 | 180 76 | 93 77 | 28 78 | 79 | 80 | 81 | 82 | Arial 83 | 84 | 85 | 86 | leave 87 | 88 | 89 | 90 | 91 | 92 | 530 93 | 250 94 | 251 95 | 171 96 | 97 | 98 | 99 | 100 | 7 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 20 111 | 30 112 | 471 113 | 391 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 540 126 | 50 127 | 111 128 | 16 129 | 130 | 131 | 132 | 133 | Arial 134 | 50 135 | false 136 | 137 | 138 | 139 | AppId: 140 | 141 | 142 | 143 | 144 | 145 | 540 146 | 70 147 | 231 148 | 31 149 | 150 | 151 | 152 | 153 | 154 | 155 | ArrowCursor 156 | 157 | 158 | 159 | 160 | 161 | 162 | 0 163 | 0 164 | 800 165 | 22 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /one_to_one_video_terminal/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = ["-C", "link-args=-Wl,-rpath,@loader_path"] -------------------------------------------------------------------------------- /one_to_one_video_terminal/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "demo" 3 | version = "0.1.0" 4 | authors = ["DongYifan "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | agorartc-sys = "*" 11 | -------------------------------------------------------------------------------- /one_to_one_video_terminal/README.md: -------------------------------------------------------------------------------- 1 | # Agora Basic One-to-One Video Call Demo (Terminal Version) 2 | 3 | *[中文](Readme.zh.md) | English* 4 | 5 | This is a Rust demo for Agora 1-to-1 video call in Terminal. 6 | 7 | ### Requirements 8 | 9 | - rustc 10 | - cargo 11 | 12 | If you are not familiar with Rust, please visit [Rust Programming Language](https://www.rust-lang.org/) for more infomation. 13 | 14 | ### Dependencies 15 | 16 | - agorartc-sys 17 | 18 | ## Run Demo 19 | 20 | 1. Add your appid to `src/main.rs`. 21 | 22 | Find the following code in `main.rs` and add your appid. *(If you do not have an App ID, see Appendix.)* 23 | 24 | ```rust 25 | static YOUR_APP_ID: &str = ""; 26 | ``` 27 | 28 | 2. Build demo. 29 | 30 | ```bash 31 | $ cargo build 32 | ``` 33 | 34 | 3. Download the required SDK. 35 | 36 | - (macOS) Download SDK [Agora Video SDK for macOS](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Mac_v3_1_2_FULL.zip). Unzip the downloaded SDK package and copy the `AograRtcEngineKit.framework` from `libs` folder into `target/debug` folder. 37 | - (Windows) Download SDK [Agora Video SDK for Windows](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Windows_v3_1_2_FULL.zip). Unzip the downloaded SDK package and copy the `agora_rtc_sdk.dll` and `agora_rtc_sdk.lib` files from `libs/x86_64` into `target/debug` folder. 38 | 39 | 4. Run demo. 40 | 41 | ```bash 42 | $ cargo run 43 | ``` 44 | 45 | ## Appendix 46 | 47 | ### Create an Account and Obtain an App ID 48 | 49 | To use our SDK, you must obtain an app ID: 50 | 51 | 1. Create a developer account at [agora.io](https://dashboard.agora.io/signin/). Once you finish the sign-up process, you are redirected to the dashboard. 52 | 2. Navigate in the dashboard tree on the left to **Projects** > **Project List**. 53 | 3. Copy the app ID that you obtained from the dashboard into a text file. You will use it when you run demo (there is an input box in our GUI demo). -------------------------------------------------------------------------------- /one_to_one_video_terminal/Readme.zh.md: -------------------------------------------------------------------------------- 1 | # Agora基础一对一视频通话示例(命令行版) 2 | 3 | *[English](README.md) | 中文* 4 | 5 | 6 | 7 | ### 运行环境 8 | 9 | - rustc 10 | - cargo 11 | 12 | 若您第一次接触Rust语言,请访问[Rust官网](https://www.rust-lang.org/zh-CN/)以获取更多信息。 13 | 14 | ### 依赖包 15 | 16 | - agorartc-sys 17 | 18 | ## 运行示例 19 | 20 | 1. 将您的appid添加至`src/main.rs`。 21 | 22 | 在`main.rs`中找到如下代码,并将您的appid添加至其中。*(如您还未获取App ID,您可以查看附录。)* 23 | 24 | ```rust 25 | static YOUR_APP_ID: &str = ""; 26 | ``` 27 | 28 | 2. 编译示例 29 | 30 | ```bash 31 | $ cargo build 32 | ``` 33 | 34 | 3. 下载所需的SDK。 35 | 36 | - (macOS)在 [Agora Video SDK for macOS](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Mac_v3_1_2_FULL.zip) 下载 SDK。解压缩之后,将 `libs` 目录下的 `AograRtcEngineKit.framework` 复制到`target/debug`中。 37 | - (Windows)在 [Agora Video SDK for Windows](https://download.agora.io/sdk/release/Agora_Native_SDK_for_Windows_v3_1_2_FULL.zip) 下载 SDK。解压缩之后,将 `libs/x86_64` 目录下的 `agora_rtc_sdk.dll` 和 `agora_rtc_sdk.lib` 复制到`target/debug`中。 38 | 39 | 4. 运行示例。 40 | 41 | ```bash 42 | $ cargo run 43 | ``` 44 | 45 | ## 附录 46 | 47 | ### 创建Agora账户并获取App ID 48 | 49 | 如果想要使用我们的SDK,您需要先获得一个App ID: 50 | 51 | 1. 在[agora.io](https://dashboard.agora.io/signin/)中注册一个账号。当您完成注册后,您将被链接至控制台。 52 | 2. 在控制台左侧点击**Projects** > **Project List**。 53 | 3. 请将您从控制台中获取的App ID保存,您将会在运行示例时使用(示例图形化界面中有输入框)。 -------------------------------------------------------------------------------- /one_to_one_video_terminal/src/main.rs: -------------------------------------------------------------------------------- 1 | // 2 | // one_to_one_video_terminal 3 | // Agora-Rust-Video-Tutorial 4 | // 5 | // Created by Yifan Dong on 2020/11/20. 6 | // Copyright © 2020 Agora. All rights reserved. 7 | // 8 | 9 | #![allow(non_upper_case_globals)] 10 | 11 | use std::io; 12 | use std::ffi::CStr; 13 | 14 | static YOUR_APP_ID: &str = ""; 15 | 16 | static RTC_ENGINE: &agorartc_sys::agorartc::Agora_Rtc_Engine = &agorartc_sys::agorartc::Agora_Rtc_Engine; 17 | 18 | unsafe extern "C" fn on_api_call_executed( 19 | err: ::std::os::raw::c_int, 20 | api: *const ::std::os::raw::c_char, 21 | result: *const ::std::os::raw::c_char, 22 | ) { 23 | let api_ = CStr::from_ptr(api); 24 | let result_ = CStr::from_ptr(result); 25 | println!("API Excuted: err {:?}, api {:?}, result {:?}", err, api_, result_); 26 | } 27 | 28 | 29 | fn main() { 30 | println!("rtcEngine: {:?}", RTC_ENGINE); 31 | println!("begin"); 32 | let mut handler = agorartc_sys::agorartc::agorartcnative::RtcEventHandler { 33 | onJoinChannelSuccess: None, 34 | onReJoinChannelSuccess: None, 35 | onLeaveChannel: None, 36 | onConnectionLost: None, 37 | onConnectionInterrupted: None, 38 | onRequestToken: None, 39 | onUserJoined: None, 40 | onUserOffline: None, 41 | onAudioVolumeIndication: None, 42 | onUserMuteAudio: None, 43 | onWarning: None, 44 | onError: None, 45 | onRtcStats: None, 46 | onAudioMixingFinished: None, 47 | onAudioRouteChanged: None, 48 | onFirstRemoteVideoDecoded: None, 49 | onVideoSizeChanged: None, 50 | onClientRoleChanged: None, 51 | onUserMuteVideo: None, 52 | onMicrophoneEnabled: None, 53 | onApiCallExecuted: Some(on_api_call_executed), 54 | onFirstLocalAudioFrame: None, 55 | onFirstRemoteAudioFrame: None, 56 | onLastmileQuality: None, 57 | onAudioQuality: None, 58 | onStreamInjectedStatus: None, 59 | onStreamUnpublished: None, 60 | onStreamPublished: None, 61 | onStreamMessageError: None, 62 | onStreamMessage: None, 63 | onConnectionBanned: None, 64 | onRemoteVideoTransportStats: None, 65 | onRemoteAudioTransportStats: None, 66 | onTranscodingUpdated: None, 67 | onAudioDeviceVolumeChanged: None, 68 | onActiveSpeaker: None, 69 | onMediaEngineStartCallSuccess: None, 70 | onMediaEngineLoadSuccess: None, 71 | onConnectionStateChanged: None, 72 | onRemoteSubscribeFallbackToAudioOnly: None, 73 | onLocalPublishFallbackToAudioOnly: None, 74 | onUserEnableLocalVideo: None, 75 | onRemoteVideoStateChanged: None, 76 | onVideoDeviceStateChanged: None, 77 | onAudioEffectFinished: None, 78 | onRemoteAudioMixingEnd: None, 79 | onRemoteAudioMixingBegin: None, 80 | onCameraExposureAreaChanged: None, 81 | onCameraFocusAreaChanged: None, 82 | onCameraReady: None, 83 | onAudioDeviceStateChanged: None, 84 | onUserEnableVideo: None, 85 | onFirstRemoteVideoFrame: None, 86 | onFirstLocalVideoFrame: None, 87 | onRemoteAudioStats: None, 88 | onRemoteVideoStats: None, 89 | onLocalVideoStats: None, 90 | onNetworkQuality: None, 91 | onTokenPrivilegeWillExpire: None, 92 | onVideoStopped: None, 93 | onAudioMixingStateChanged: None, 94 | onFirstRemoteAudioDecoded: None, 95 | onLocalVideoStateChanged: None, 96 | onNetworkTypeChanged: None, 97 | onRtmpStreamingStateChanged: None, 98 | onLastmileProbeResult: None, 99 | onLocalUserRegistered: None, 100 | onUserInfoUpdated: None, 101 | onLocalAudioStateChanged: None, 102 | onRemoteAudioStateChanged: None, 103 | onLocalAudioStats: None, 104 | onChannelMediaRelayStateChanged: None, 105 | onChannelMediaRelayEvent: None, 106 | onFacePositionChanged: None, 107 | onTestEnd: None, 108 | }; 109 | println!("begin 2"); 110 | RTC_ENGINE.add_event_handler(&mut handler as *mut _); 111 | RTC_ENGINE.initialize(YOUR_APP_ID, agorartc_sys::agorartc::AREA_CODE::AREA_CODE_GLOBAL); 112 | RTC_ENGINE.enable_video(); 113 | { 114 | let video_device_manager = RTC_ENGINE.create_video_device_manager(); 115 | let count = video_device_manager.get_device_count(); 116 | println!("video device count: {}", count); 117 | 118 | let (name, id, ret) = video_device_manager.get_device(0); 119 | println!("device: {}, {}, {}", name, id, ret); 120 | } 121 | RTC_ENGINE.join_channel("", "123", "", 0u32); 122 | let mut input = String::new(); 123 | io::stdin().read_line(&mut input).expect("error: unable to read user input"); 124 | println!("{}", input); 125 | RTC_ENGINE.leave_channel(); 126 | RTC_ENGINE.release(true); 127 | } -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = ["-C", "link-args=-Wl,-rpath,@loader_path"] -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "copy_dlib", 4 | "demo" 5 | ] -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/README.md: -------------------------------------------------------------------------------- 1 | # Agora Basic One-to-One Video Call Demo (Terminal Version with Dynamic Library Copy Program) 2 | 3 | *[中文](Readme.zh.md) | English* 4 | 5 | This is a Rust demo for Agora 1-to-1 video call in Terminal including a dynamic library copy program which can automatically find the required Agora dynamic library in your system and add it to the right path. 6 | 7 | ### Requirements 8 | 9 | - rustc 10 | - cargo 11 | 12 | If you are not familiar with Rust, please visit [Rust Programming Language](https://www.rust-lang.org/) for more infomation. 13 | 14 | ### Dependencies 15 | 16 | - agorartc-sys 17 | 18 | ## Run Demo 19 | 20 | 1. Add your appid to `demo/src/main.rs`. 21 | 22 | Find the following code in `main.rs` and add your appid. *(If you do not have an App ID, see Appendix.)* 23 | 24 | ```rust 25 | static YOUR_APP_ID: &str = ""; 26 | ``` 27 | 28 | 2. Build demo. 29 | 30 | Make sure that you run the following instruction under `.../one_to_one_video_terminal_enhanced` path instead of `.../one_to_one_video_terminal_enhanced/demo` so that both programs can be compiled together. 31 | 32 | ```bash 33 | $ cargo build 34 | ``` 35 | 36 | 3. Run copy program. 37 | 38 | ```bash 39 | $ cargo run --bin copy_dlib 40 | ``` 41 | 42 | 4. Run demo. 43 | 44 | ```bash 45 | $ cargo run --bin demo 46 | ``` 47 | 48 | ## Appendix 49 | 50 | ### Create an Account and Obtain an App ID 51 | 52 | To use our SDK, you must obtain an app ID: 53 | 54 | 1. Create a developer account at [agora.io](https://dashboard.agora.io/signin/). Once you finish the sign-up process, you are redirected to the dashboard. 55 | 2. Navigate in the dashboard tree on the left to **Projects** > **Project List**. 56 | 3. Copy the app ID that you obtained from the dashboard into a text file. You will use it when you run demo (there is an input box in our GUI demo). -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/Readme.zh.md: -------------------------------------------------------------------------------- 1 | # Agora基础一对一视频通话示例(命令行版附加拷贝动态库脚本) 2 | 3 | *[English](README.md) | 中文* 4 | 5 | 6 | 7 | ### 运行环境 8 | 9 | - rustc 10 | - cargo 11 | 12 | 若您第一次接触Rust语言,请访问[Rust官网](https://www.rust-lang.org/zh-CN/)以获取更多信息。 13 | 14 | ### 依赖包 15 | 16 | - agorartc-sys 17 | 18 | ## 运行示例 19 | 20 | 1. 将您的appid添加至`demo/src/main.rs`。 21 | 22 | 在`main.rs`中找到如下代码,并将您的appid添加至其中。*(如您还未获取App ID,您可以查看附录。)* 23 | 24 | ```rust 25 | static YOUR_APP_ID: &str = ""; 26 | ``` 27 | 28 | 2. 编译示例 29 | 30 | 确保您在`.../one_to_one_video_terminal_enhanced`路经下运行以下命令而不是`.../one_to_one_video_terminal_enhanced/demo`,这样两个程序可以被一起编译。 31 | 32 | ```bash 33 | $ cargo build 34 | ``` 35 | 36 | 3. 运行复制脚本 37 | 38 | ```bash 39 | $ cargo run --bin copy_dlib 40 | ``` 41 | 42 | 4. 运行示例。 43 | 44 | ```bash 45 | $ cargo run --bin demo 46 | ``` 47 | 48 | ## 附录 49 | 50 | ### 创建Agora账户并获取App ID 51 | 52 | 如果想要使用我们的SDK,您需要先获得一个App ID: 53 | 54 | 1. 在[agora.io](https://dashboard.agora.io/signin/)中注册一个账号。当您完成注册后,您将被链接至控制台。 55 | 2. 在控制台左侧点击**Projects** > **Project List**。 56 | 3. 请将您从控制台中获取的App ID保存,您将会在运行示例时使用(示例图形化界面中有输入框)。 -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/copy_dlib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "copy_dlib" 3 | version = "0.1.0" 4 | authors = ["Yiqing Huang "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | walkdir = "2.3.1" -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/copy_dlib/src/main.rs: -------------------------------------------------------------------------------- 1 | // 2 | // one_to_one_video_terminal 3 | // Agora-Rust-Video-Tutorial 4 | // 5 | // Created by Yiqing Huang on 2020/11/20. 6 | // Copyright © 2020 Agora. All rights reserved. 7 | // 8 | 9 | use std::ops::Add; 10 | use std::env; 11 | use walkdir::WalkDir; 12 | 13 | fn main() { 14 | WalkDir::new(env::var("CARGO_HOME").unwrap().add("/registry/src/")) 15 | .into_iter() 16 | .filter_map(|v| v.ok()) 17 | .for_each(|x| if x.depth() == 2 && x.file_name().to_str().unwrap().contains("agora") { 18 | if cfg!(target_os = "windows") { 19 | std::process::Command::new("cmd") 20 | .args(&["/C", "cp ".to_string().add(x.path().to_str().unwrap()).add("/vender/agora_rtc_sdk.dll target/debug").as_str()]) 21 | .output() 22 | .expect("failed"); 23 | } else { 24 | std::process::Command::new("sh") 25 | .arg("-c") 26 | .arg("cp -r ".to_string().add(x.path().to_str().unwrap()).add("/vender/AgoraRtcKit.framework target/debug")) 27 | .output() 28 | .expect("failed"); 29 | } 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/demo/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = ["-C", "link-args=-Wl,-rpath,@loader_path"] -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/demo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "demo" 3 | version = "0.1.0" 4 | authors = ["DongYifan "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | agorartc-sys = "*" 11 | -------------------------------------------------------------------------------- /one_to_one_video_terminal_enhanced/demo/src/main.rs: -------------------------------------------------------------------------------- 1 | // 2 | // one_to_one_video_terminal 3 | // Agora-Rust-Video-Tutorial 4 | // 5 | // Created by Yifan Dong on 2020/11/20. 6 | // Copyright © 2020 Agora. All rights reserved. 7 | // 8 | 9 | #![allow(non_upper_case_globals)] 10 | 11 | use std::io; 12 | use std::ffi::CStr; 13 | 14 | static YOUR_APP_ID: &str = ""; 15 | 16 | static RTC_ENGINE: &agorartc_sys::agorartc::Agora_Rtc_Engine = &agorartc_sys::agorartc::Agora_Rtc_Engine; 17 | 18 | unsafe extern "C" fn on_api_call_executed( 19 | err: ::std::os::raw::c_int, 20 | api: *const ::std::os::raw::c_char, 21 | result: *const ::std::os::raw::c_char, 22 | ) { 23 | let api_ = CStr::from_ptr(api); 24 | let result_ = CStr::from_ptr(result); 25 | println!("API Excuted: err {:?}, api {:?}, result {:?}", err, api_, result_); 26 | } 27 | 28 | 29 | fn main() { 30 | println!("rtcEngine: {:?}", RTC_ENGINE); 31 | println!("begin"); 32 | let mut handler = agorartc_sys::agorartc::agorartcnative::RtcEventHandler { 33 | onJoinChannelSuccess: None, 34 | onReJoinChannelSuccess: None, 35 | onLeaveChannel: None, 36 | onConnectionLost: None, 37 | onConnectionInterrupted: None, 38 | onRequestToken: None, 39 | onUserJoined: None, 40 | onUserOffline: None, 41 | onAudioVolumeIndication: None, 42 | onUserMuteAudio: None, 43 | onWarning: None, 44 | onError: None, 45 | onRtcStats: None, 46 | onAudioMixingFinished: None, 47 | onAudioRouteChanged: None, 48 | onFirstRemoteVideoDecoded: None, 49 | onVideoSizeChanged: None, 50 | onClientRoleChanged: None, 51 | onUserMuteVideo: None, 52 | onMicrophoneEnabled: None, 53 | onApiCallExecuted: Some(on_api_call_executed), 54 | onFirstLocalAudioFrame: None, 55 | onFirstRemoteAudioFrame: None, 56 | onLastmileQuality: None, 57 | onAudioQuality: None, 58 | onStreamInjectedStatus: None, 59 | onStreamUnpublished: None, 60 | onStreamPublished: None, 61 | onStreamMessageError: None, 62 | onStreamMessage: None, 63 | onConnectionBanned: None, 64 | onRemoteVideoTransportStats: None, 65 | onRemoteAudioTransportStats: None, 66 | onTranscodingUpdated: None, 67 | onAudioDeviceVolumeChanged: None, 68 | onActiveSpeaker: None, 69 | onMediaEngineStartCallSuccess: None, 70 | onMediaEngineLoadSuccess: None, 71 | onConnectionStateChanged: None, 72 | onRemoteSubscribeFallbackToAudioOnly: None, 73 | onLocalPublishFallbackToAudioOnly: None, 74 | onUserEnableLocalVideo: None, 75 | onRemoteVideoStateChanged: None, 76 | onVideoDeviceStateChanged: None, 77 | onAudioEffectFinished: None, 78 | onRemoteAudioMixingEnd: None, 79 | onRemoteAudioMixingBegin: None, 80 | onCameraExposureAreaChanged: None, 81 | onCameraFocusAreaChanged: None, 82 | onCameraReady: None, 83 | onAudioDeviceStateChanged: None, 84 | onUserEnableVideo: None, 85 | onFirstRemoteVideoFrame: None, 86 | onFirstLocalVideoFrame: None, 87 | onRemoteAudioStats: None, 88 | onRemoteVideoStats: None, 89 | onLocalVideoStats: None, 90 | onNetworkQuality: None, 91 | onTokenPrivilegeWillExpire: None, 92 | onVideoStopped: None, 93 | onAudioMixingStateChanged: None, 94 | onFirstRemoteAudioDecoded: None, 95 | onLocalVideoStateChanged: None, 96 | onNetworkTypeChanged: None, 97 | onRtmpStreamingStateChanged: None, 98 | onLastmileProbeResult: None, 99 | onLocalUserRegistered: None, 100 | onUserInfoUpdated: None, 101 | onLocalAudioStateChanged: None, 102 | onRemoteAudioStateChanged: None, 103 | onLocalAudioStats: None, 104 | onChannelMediaRelayStateChanged: None, 105 | onChannelMediaRelayEvent: None, 106 | onFacePositionChanged: None, 107 | onTestEnd: None, 108 | }; 109 | println!("begin 2"); 110 | RTC_ENGINE.add_event_handler(&mut handler as *mut _); 111 | RTC_ENGINE.initialize(YOUR_APP_ID, agorartc_sys::agorartc::AREA_CODE::AREA_CODE_GLOBAL); 112 | RTC_ENGINE.enable_video(); 113 | { 114 | let video_device_manager = RTC_ENGINE.create_video_device_manager(); 115 | let count = video_device_manager.get_device_count(); 116 | println!("video device count: {}", count); 117 | 118 | let (name, id, ret) = video_device_manager.get_device(0); 119 | println!("device: {}, {}, {}", name, id, ret); 120 | } 121 | RTC_ENGINE.join_channel("", "123", "", 0u32); 122 | let mut input = String::new(); 123 | io::stdin().read_line(&mut input).expect("error: unable to read user input"); 124 | println!("{}", input); 125 | RTC_ENGINE.leave_channel(); 126 | RTC_ENGINE.release(true); 127 | } --------------------------------------------------------------------------------