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

news/2025/2/21 7:47:38

下面是一个使用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>

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


http://www.niftyadmin.cn/n/5860482.html

相关文章

leetcode:3110. 字符串的分数(python3解法)

难度&#xff1a;简单 给你一个字符串 s 。一个字符串的 分数 定义为相邻字符 ASCII 码差值绝对值的和。 请你返回 s 的 分数 。 示例 1&#xff1a; 输入&#xff1a;s "hello" 输出&#xff1a;13 解释&#xff1a; s 中字符的 ASCII 码分别为&#xff1a;h 104 …

修改阿里云服务器内网ip

运维同事问能不能改我自己的服务内网ip&#xff0c; 买了一台服99元服务器&#xff0c;以为不能结果&#xff0c;结果还真改成功了&#xff0c; 分享一下经验。 首先最后关闭服务器-关机&#xff0c;必须要关闭服务 访问vpc控制台&#xff0c;就是要新建立一个网络 https://…

角点检测算法各自优缺点

在计算机视觉领域&#xff0c;角点检测是一个基础且重要的任务&#xff0c;SIFT、Harris、Shi - Tomasi、FAST 都是经典的角点检测算法&#xff0c;它们各自具有独特的优缺点。 SIFT&#xff08;尺度不变特征变换&#xff09; 优点 尺度不变性&#xff1a;SIFT 能够在不同尺度…

一款开源可独立部署的知识管理工具!!

今天给大家介绍一款开源的知识管理工具——云策文档。 介绍 该系统通过独立的知识库空间&#xff0c;结构化地组织在线协作文档&#xff0c;实现知识的积累与沉淀&#xff0c;促进知识的复用与流通。同时支持多人协作文档。 云策文档设计了明确的权限管理&#xff0c;方便文档…

86.多零件流水线优化问题|Marscode AI刷题

1.题目 问题描述 小C、小U、小R是工厂里的三个工人&#xff0c;他们互相协同制作零件。零件的制作包括三种工序&#xff1a;"加工"、"质检"、"收尾"&#xff0c;分别由小C、小U、小R负责。每个零件需要多次进行"加工"和"质检&q…

火绒终端安全管理系统V2.0【系统防御功能】

火绒企业版V2.0系统防御功能包含系统加固、应用加固、软件安装拦截、摄像头保护和浏览器保护。火绒终端安全管理软件V2.0守护企业用户终端安全。 系统防御 1. 系统加固 系统加固功能根据火绒提供的安全加固策略&#xff0c;当程序对特定系统资源操作时提醒用户可能存在的安…

【架构设计】总览(更新中)

技术人员的职业规划和发展&#xff1a;不仅要关注专业技术&#xff08;术&#xff09;&#xff0c;还要有自己的分析能力&#xff08;道&#xff09;&#xff0c;并且要懂得顺势而为&#xff08;势&#xff09;。很多事情你看似简单&#xff0c;但其中会有很多思考&#xff08;…

设计模式教程:装饰器模式(Decorator Pattern)

1. 什么是装饰器模式&#xff1f; 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许在不修改对象结构的情况下&#xff0c;动态地为对象添加额外的功能。装饰器模式使用组合&#xff08;而不是继承&#xff09;来扩展对象的功能&a…