当前位置: 首页 > news >正文

UNIAPP开发之利用阿里RTC服务实现音视频通话后端THINKPHP5

下面是一个使用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和AppKey
    private $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>

运行项目

  1. 启动后端服务器
php think run
  1. 启动UniApp项目

在HBuilderX中打开你的UniApp项目,然后点击运行按钮,选择合适的模拟器或真机进行测试。

注意事项

  1. 阿里云RTC的URL格式

    • 上述示例中的pushUrlplayUrl是示例格式,你需要根据阿里云RTC的实际文档来调整URL格式。
    • 确保你已经正确配置了阿里云RTC的推流和播流地址。
  2. 安全性

    • 在生产环境中,确保你的后端服务和Token生成逻辑是安全的,防止未授权访问。
  3. 网络环境

    • 测试时,请确保网络环境稳定,以获得更好的音视频通话体验。

通过以上步骤,你应该能够实现一个基本的UniApp音视频通话功能,并使用ThinkPHP 5作为后端来处理音视频流。如果有任何问题或需要进一步的帮助,请随时提问。


同样我们可以更完善一下前端的代码例如增加上开始通话和结束通话的功能

<template>
  <view class="container">
    <view class="video-container">
      <!-- 本地视频预览 -->
      <live-pusher
        ref="livePusher"
        :url="pushUrl"
        mode="RTC"
        autopush
        @statechange="onPushStateChange"
        class="live-pusher"
      ></live-pusher>
      <!-- 远程视频播放 -->
      <live-player
        ref="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>

总而言之是需要大家去一步步的实践的。如果有更好的实现方式请分享反馈给我们

相关文章:

  • 磐维数据库双中心容灾流复制集群搭建
  • K8S下redis哨兵集群使用secret隐藏configmap内明文密码方案详解
  • 我的文具盒作文范文
  • windows使用命令解压jar包,替换里面的文件。并重新打包成jar包,解决Failed to get nested archive for entry
  • 软件单元测试的技术要求
  • 日期类(完全讲解版)
  • 【Server Components 解析:Next.js 的未来组件模型】
  • Unity for Python —— 强大的 Python 脚本支持提升 Unity 编辑器效率
  • 前沿科技:改变生活的十大趋势
  • 后端开发:开启技术世界的新大门
  • playwright 实现自动上传,多元素操作
  • 性能:React 实战优化技巧 之 函数闭包
  • 一文讲解Redis为什么读写性能高以及I/O复用相关知识点
  • python读取pdf文档
  • 学习 `@PreDestroy`:Java EE/Jakarta EE 生命周期回调
  • web安全:跨站请求伪造 (CSRF)
  • Spark(2)linux和简单命令
  • Python 关于顶层对象
  • k8s Container runtime network not ready
  • 知识图谱-学习计划
  • 上海车展迎来超百款首发新车,全市多区开展汽车促消费活动
  • 著名诗人、中国城市发展研究院原常务副院长吕贵品逝世
  • 大家聊中国式现代化|彭羽:为国家试制度探新路,推进高水平对外开放
  • 去年9月就提出辞任中国乒协主席,刘国梁谈辞职原因
  • 东方富海陈玮: 什么样的创业者能让天使投资人愿意下注
  • 成都两宗宅地成功出让,民企四川联投溢价33%竞得郫都区宅地