下面是一個使用ThinkPHP 5實現后端邏輯的示例。我們將創建一個簡單的ThinkPHP 5項目來處理生成推流和播流地址的請求。
后端部分(ThinkPHP 5)
1. 初始化ThinkPHP 5項目
首先,確保你已經安裝了Composer。然后使用Composer創建一個新的ThinkPHP 5項目。
composer create-project topthink/think tp5-rtc-demo
cd tp5-rtc-demo
2. 安裝依賴
ThinkPHP 5自帶了一些必要的依賴,我們還需要安裝guzzlehttp/guzzle
來處理HTTP請求。
composer require guzzlehttp/guzzle
3. 創建控制器
在application/index/controller
目錄下創建一個新的控制器文件Rtc.php
。
<?php
namespace app\index\controller;use think\Controller;
use GuzzleHttp\Client;class Rtc extends Controller
{// 阿里云RTC的AppID和AppKeyprivate $appId = 'your_app_id';private $appKey = 'your_app_key';// 生成Token的函數private function generateToken($userId, $channelName){$timestamp = time() + 3600; // 1小時有效期$nonce = bin2hex(random_bytes(15));$signature = hash_hmac('sha1', $this->appId . $channelName . $userId . $timestamp . $nonce, $this->appKey);return '0001' . $this->appId . $channelName . $userId . $timestamp . $nonce . $signature;}// 處理獲取推流和播流地址的請求public function getRtcToken(){$userId = input('post.userId');$otherUserId = input('post.otherUserId');$channelName = 'room1'; // 可以根據需要動態生成房間名$token = $this->generateToken($userId, $channelName);$pushUrl = "wss://your-rtc-push-url/{$channelName}?token={$token}";$playUrl = "wss://your-rtc-play-url/{$channelName}?token={$token}";return json(['pushUrl' => $pushUrl, 'playUrl' => $playUrl]);}
}
4. 配置路由
在route/route.php
中添加路由規則。
use think\Route;Route::post('get-rtc-token', 'index/Rtc/getRtcToken');
5. 啟動ThinkPHP 5服務器
在項目根目錄下啟動ThinkPHP 5內置服務器。
php think run
默認情況下,服務器會在http://localhost:8000
上運行。
前端部分
前端部分與之前的示例保持一致,只需將后端URL改為ThinkPHP 5的地址。
1. 編寫前端代碼
在pages/index/index.vue
中編寫以下代碼:
<template><view><!-- 本地視頻預覽 --><live-pusher :url="pushUrl" mode="RTC" autopush @statechange="onPushStateChange"></live-pusher><!-- 遠程視頻播放 --><live-player :src="playUrl" mode="RTC" autoplay @statechange="onPlayStateChange"></live-player></view>
</template><script>
export default {data() {return {pushUrl: '',playUrl: '',};},methods: {onPushStateChange(e) {console.log('推流狀態變化', e);},onPlayStateChange(e) {console.log('播放狀態變化', e);},// 獲取推流和播流地址的邏輯async getRTCToken() {const response = await uni.request({url: 'http://localhost:8000/get-rtc-token',method: 'POST',data: {userId: 'user1',otherUserId: 'user2',},});this.pushUrl = response.data.pushUrl;this.playUrl = response.data.playUrl;},},onLoad() {this.getRTCToken();},
};
</script><style>
/* 添加一些樣式 */
live-pusher, live-player {width: 100%;height: 300px;
}
</style>
運行項目
- 啟動后端服務器
php think run
- 啟動UniApp項目
在HBuilderX中打開你的UniApp項目,然后點擊運行按鈕,選擇合適的模擬器或真機進行測試。
注意事項
-
阿里云RTC的URL格式:
- 上述示例中的
pushUrl
和playUrl
是示例格式,你需要根據阿里云RTC的實際文檔來調整URL格式。 - 確保你已經正確配置了阿里云RTC的推流和播流地址。
- 上述示例中的
-
安全性:
- 在生產環境中,確保你的后端服務和Token生成邏輯是安全的,防止未授權訪問。
-
網絡環境:
- 測試時,請確保網絡環境穩定,以獲得更好的音視頻通話體驗。
通過以上步驟,你應該能夠實現一個基本的UniApp音視頻通話功能,并使用ThinkPHP 5作為后端來處理音視頻流。如果有任何問題或需要進一步的幫助,請隨時提問。
同樣我們可以更完善一下前端的代碼例如增加上開始通話和結束通話的功能
<template><view class="container"><view class="video-container"><!-- 本地視頻預覽 --><live-pusherref="livePusher":url="pushUrl"mode="RTC"autopush@statechange="onPushStateChange"class="live-pusher"></live-pusher><!-- 遠程視頻播放 --><live-playerref="livePlayer":src="playUrl"mode="RTC"autoplay@statechange="onPlayStateChange"class="live-player"></live-player></view><view class="controls"><button @click="startCall" :disabled="isCalling" class="control-button">開始通話</button><button @click="endCall" :disabled="!isCalling" class="control-button">結束通話</button></view></view>
</template><script>
export default {data() {return {pushUrl: '',playUrl: '',isCalling: false,};},methods: {onPushStateChange(e) {console.log('推流狀態變化', e);},onPlayStateChange(e) {console.log('播放狀態變化', e);},// 獲取推流和播流地址的邏輯async getRTCToken() {const response = await uni.request({url: 'http://localhost:8000/get-rtc-token',method: 'POST',data: {userId: 'user1',otherUserId: 'user2',},});this.pushUrl = response.data.pushUrl;this.playUrl = response.data.playUrl;},startCall() {this.$refs.livePusher.start();this.$refs.livePlayer.play();this.isCalling = true;},endCall() {this.$refs.livePusher.stop();this.$refs.livePlayer.stop();this.isCalling = false;},},onLoad() {this.getRTCToken();},
};
</script><style>
/* 添加一些樣式 */
.container {display: flex;flex-direction: column;align-items: center;justify-content: center;height: 100vh;background-color: #f0f0f0;
}.video-container {display: flex;flex-direction: row;justify-content: space-around;width: 100%;max-width: 800px;margin-bottom: 20px;
}.live-pusher, .live-player {width: 45%;height: 300px;border: 1px solid #ccc;border-radius: 10px;overflow: hidden;
}.controls {display: flex;flex-direction: row;justify-content: space-around;width: 100%;max-width: 400px;
}.control-button {padding: 10px 20px;font-size: 16px;color: #fff;background-color: #007aff;border: none;border-radius: 5px;cursor: pointer;
}.control-button:disabled {background-color: #ccc;cursor: not-allowed;
}
</style>
總而言之是需要大家去一步步的實踐的。如果有更好的實現方式請分享反饋給我們