linux 运行开源音视频livekit,实现html视频语音聊天。

时而有事儿 2024-07-19 15:07:03 阅读 68

linux版本:

centos 7.9

先附上官方本地安装文档:

Running LiveKit locally | LiveKit Docs

步骤:

1、首先在linux里面安装运行livekit:

<code>1.任意目录创建文件livekit,cd到livkit目录,然后在livekit目录下运行下面的命令。

2.安装服务

curl -sSL https://get.livekit.io | bash

3.先测试运行,8.218.***.**替换成你的ip,是云服务器就替换成公网IP,局域网就用局域网ip

livekit-server --dev --node-ip=8.218.***.** --bind 0.0.0.0

结束运行按键盘:ctrl+c

4.带配置文件运行

可以直接根据配置文件运行

livekit-server --config ./livekit.yaml --node-ip=8.218.***.** --bind 0.0.0.0

结束运行按键盘:ctrl+c

5.后台运行,在livekit目录创建run.sh文件,然后运行命令

sh run.sh

livekit.yaml文件的内容:

port: 7880

rtc:

udp_port: 7882

tcp_port: 7881

use_external_ip: true

enable_loopback_candidate: false

keys:

APIbxDWetqcjHaa: RlZfytYLmdMOgV2u6fSFAbMhrYQok9B4aVWq48eIE1aa

logging:

json: false

level: info

注意use_external_ip一定要设置true.这个是启用外部ip访问的。

然后就是keys:这个是创建token需要的,

前面的APIbxDWetqcjHaa是apikey,

后面的RlZfytYLmdMOgV2u6fSFAbMhrYQok9B4aVWq48eIE1aa是secret。

再附上run.sh,这个是后台运行的:

#!/bin/sh

nohup livekit-server --config ./livekit.yaml > log.log 2>&1 &

测试是否运行成功。浏览器输入http://8.218.***.**:7880/,显示ok及代表运行成功。

2、创建token。

token是客户端访问livekit服务器所需要的凭证,里面包含了房间名称和用户id等信息。

我是用java创建token,还有其他方式创建token的办法,详见官方文档。

Authentication | LiveKit Docs

java创建token的方法:

首先导入maven包:

<code>

<dependency>

<groupId>io.livekit</groupId>

<artifactId>livekit-server</artifactId>

<version>0.5.9</version>

</dependency>

然后随便创建一个main方法:

package com.example.demo1;

import io.livekit.server.*;

import java.util.ArrayList;

import java.util.Date;

import java.util.List;

public class LiveKitTest {

public static void main(String[] args) {

System.out.println(createToken(100));

System.out.println(createToken(101));

System.out.println(createToken(102));

System.out.println(createToken(103));

// System.out.println(createToken(96));

// System.out.println(createToken(98));

}

public static String createToken(int num) {

// 用户ID

int userID = 10000+num;

// 用户名称

String name = "用户"+num;

String roomName = "测试房间2";

String apiKey = "APIbxDWetqcjHaa";

String apiSecret = "RlZfytYLmdMOgV2u6fSFAbMhrYQok9B4aVWq48eIE1aa";

AccessToken token = new AccessToken(apiKey, apiSecret);

token.setName(name);

token.setIdentity(userID+"");

token.setMetadata("metadata");

// 令牌的过期时间(可能)

token.setExpiration(new Date(System.currentTimeMillis()+ 1000L *60*60*24*365));

// token所拥有的权限

List<String> list = new ArrayList<>();

// 摄像头

list.add("camera");

// 麦克风

list.add("microphone");

// list.add("screen_share"); //屏幕共享

// list.add("screen_share_audio"); //屏幕共享音频

// 允许参与者发布相机,但不允许其他来源

CanPublishSources canPublishSources = new CanPublishSources(list);

// 配置解释:https://docs.livekit.io/realtime/concepts/authentication/

// RoomJoin:加入房间许可 Room:房间名称

token.addGrants(new RoomJoin(true), new Room(roomName),canPublishSources);

return token.toJwt();

}

}

这里面的apikey和apisecret就是livekit.yam文件里面的。

运行main方法即可得出类似这样的token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMDEwMCIsIm1ldGFkYXRhIjoibWV0YWRhdGEiLCJpc3MiOiJBUElieERXZXRxY2pIM2siLCJuYW1lIjoi55So5oi3MTAwIiwidmlkZW8iOnsicm9vbUpvaW4iOnRydWUsInJvb20iOiLmtYvor5XmiL_pl7QyIiwiY2FuUHVibGlzaFNvdXJjZXMiOlsiY2FtZXJhIiwibWljcm9waG9uZSJdfSwiZXhwIjoxNzQxOTQzOTc1LCJqdGkiOiIxMDEwMCJ9.lkjLjZb6qv96DxTxIUpLLUJSVdILaNi7_IeqZzLDbhA

这样token就创建成功了。

3.测试运行

我这里使用的是html+js测试的。

其他客户端运行方式可以看官方文档:

Client Quickstarts | LiveKit Docs

这里附上html源码:

<!DOCTYPE html>

<html lang="en">code>

<head>

<meta charset="UTF-8">code>

<meta name="viewport" content="width=device-width, initial-scale=1.0">code>

<title>LiveKit Example</title>

</head>

<body>

<div id="videoTestDiv"></div>code>

<div id="videoDiv" style="width: 80%"></div>code>

<input type="text" id="tokenInput" value=""/>code>

<br/>

<button onclick="user1Fun()" style="margin: 10px;">用户90</button>code>

<button onclick="user2Fun()" style="margin: 10px;">用户92</button>code>

<button onclick="user3Fun()" style="margin: 10px;">用户96</button>code>

<button onclick="user4Fun()" style="margin: 10px;">用户98</button>code>

<br/>

<button onclick="connect()" style="margin: 10px;">视频链接</button>code>

<button onclick="connect()" style="margin: 10px;">语音链接</button>code>

<button onclick="ext()" style="margin: 10px;">登出</button>code>

<button onclick="openVideo()" style="margin: 10px;">打开摄像头</button>code>

<script src="livekit-client.umd.min.js"></script>code>

<script src="eruda.js"></script>code>

<script>

// 手机上的调试插件

eruda.init();

const tokenInput = document.getElementById("tokenInput");

// 获取页面的高度和宽度

let pageHeight = document.documentElement.clientHeight;

let pageWidth = document.documentElement.clientWidth;

user1Fun();

// 检查是否支持webrtc和是否存在麦克风和摄像头

// 如果手机上访问必须是https,不是则调用不了麦克风和摄像头

// checkVideo();

// const wsURL = "wss://gscs.yuming.com:7443"

const wsURL = "ws://8.218.***.**:7880"

const room = new LivekitClient.Room({

// 自动管理订阅的视频质量

adaptiveStream: true,

// 优化已发布曲目的发布带宽和CPU

dynacast: true,

// 默认捕获设置

videoCaptureDefaults: {

resolution: LivekitClient.VideoPresets.h720.resolution,

},

});

// 链接livekit

async function connect() {

let token = tokenInput.value;

console.log(token);

console.log(wsURL);

if (token == "") {

alert("请输入token");

return;

}

// 预热连接,这可以在页面加载后立即调用

// room.prepareConnection(wsURL, token);

// 设置事件侦听器

allHandle();

// 链接

await room.connect(wsURL, token);

console.log('链接成功', room.roomInfo);

alert('链接成功');

// 发布本地相机和麦克风曲目 下面可以单独开麦克风和相机

// await room.localParticipant.enableCameraAndMicrophone();

const p = room.localParticipant;

// 打开本地用户的相机和麦克风,这可能会触发浏览器提示

// 以确保授予权限

await p.setCameraEnabled(true);

await p.setMicrophoneEnabled(true);

// 开始共享用户的屏幕,这将触发浏览器提示选择

// 要共享的屏幕。

// await p.setScreenShareEnabled(true);

}

// 所有监听事件

function allHandle() {

// 房间有人加入事件

room.on(LivekitClient.RoomEvent.ParticipantConnected, function () {

console.log("一个远程参与者 在本地参与者之后加入。");

})

room.on(LivekitClient.RoomEvent.ParticipantDisconnected, function () {

console.log("远程参与者离开");

})

room.on(LivekitClient.RoomEvent.Reconnecting, function () {

console.log("与服务器的连接已中断,它正在尝试重新连接。");

})

room.on(LivekitClient.RoomEvent.Reconnected, function () {

console.log("重新连接已成功");

})

room.on(LivekitClient.RoomEvent.Disconnected, function () {

console.log("由于房间关闭或无法恢复的故障而与房间断开连接");

})

room.on(LivekitClient.RoomEvent.TrackPublished, function () {

console.log("本地参与者加入后,新曲目将发布到房间");

})

room.on(LivekitClient.RoomEvent.TrackUnpublished, function () {

console.log("远程参与者已取消发布轨道");

})

room.on(LivekitClient.RoomEvent.TrackMuted, function () {

console.log("轨道被静音,本地轨道和远程轨道都会触发");

})

room.on(LivekitClient.RoomEvent.TrackUnmuted, function () {

console.log("轨道未静音,本地轨道和远程轨道都会触发");

})

room.on(LivekitClient.RoomEvent.LocalTrackPublished, function () {

console.log("本地曲目已成功发布");

})

room.on(LivekitClient.RoomEvent.LocalTrackUnpublished, function (track, publication, participant) {

console.log("本地曲目未发布");

publication.track.detach();

})

room.on(LivekitClient.RoomEvent.ActiveSpeakersChanged, function () {

console.log("当前活动的发言人已更改");

})

room.on(LivekitClient.RoomEvent.IsSpeakingChanged, function () {

console.log("当前参与者已更改发言状态");

})

// 参与者的连接质量已更改

room.on(LivekitClient.RoomEvent.ConnectionQualityChanged, function () {

console.log("参与者的连接质量已更改");

})

room.on(LivekitClient.RoomEvent.ParticipantMetadataChanged, function () {

console.log("通过服务器API更新了参与者的元数据");

})

room.on(LivekitClient.RoomEvent.RoomMetadataChanged, function () {

console.log("与房间相关联的元数据已更改");

})

room.on(LivekitClient.RoomEvent.DataReceived, function () {

console.log("从另一个参与者或服务器接收的数据");

})

// 指示订阅的曲目是否因带宽而暂停

room.on(LivekitClient.RoomEvent.TrackStreamStateChanged, function () {

console.log("指示订阅的曲目是否因带宽原因而暂停");

})

room.on(LivekitClient.RoomEvent.TrackSubscriptionPermissionChanged, function () {

console.log("订阅的曲目之一已更改当前参与者的曲目级别权限");

})

room.on(LivekitClient.RoomEvent.ParticipantPermissionsChanged, function () {

console.log("当前参与者的权限更改时");

})

// 有新成员加入是会访问这个方法

room.on(LivekitClient.RoomEvent.TrackSubscribed, handleTrackSubscribed)

// 曲目取消订阅

room.on(LivekitClient.RoomEvent.TrackUnsubscribed, function (track, publication, participant) {

track.detach();

let videoDiv = document.getElementById("videoDiv");

videoDiv.innerHTML="";code>

console.log("有人退出了房间!")

})

}

// 从服务器接收曲目始于订阅。有新成员加入是会访问这个方法

function handleTrackSubscribed(track, publication, participant) {

console.log("有人加入了房间!")

// 将音轨附加到新的HTMLVideoElement或HTMLAudioElement

const element = track.attach();

let videoDiv = document.getElementById("videoDiv");

videoDiv.appendChild(element);

let video = videoDiv.querySelector("video");

if (video) {

video.style.width = pageWidth + "px";

video.style.height = (pageHeight - 200) + "px";

}

// 或附加到现有元素

// track.attach(element)

}

// 退出登录

function ext() {

room.disconnect();

}

function user1Fun() {

// 我是90

tokenInput.value = ""

}

function user2Fun() {

// 我是92

tokenInput.value = ""

}

function user3Fun() {

// 我是96

tokenInput.value = ""

}

function user4Fun() {

// 我是98

tokenInput.value = ""

}

// 打开摄像头

function openVideo() {

let videoTestDiv = document.getElementById("videoTestDiv");

// 创建一个新的 video 元素

const videoElement = document.createElement('video');

videoElement.style.width = pageWidth + "px";

videoElement.style.height = (pageHeight - 200) + "px";

videoElement.setAttribute('playsinline', '');

videoElement.setAttribute('autoPlay', '');

videoTestDiv.appendChild(videoElement);

navigator.mediaDevices.getUserMedia({video: true, audio: true}).then(function (stream) {

console.log(stream);

videoElement.srcObject = stream;

// videoTest.src = window.webkitURL.createObjectURL(stream);

});

}

/**

* 检查摄像头和麦克风是否可用

*/

function checkVideo() {

// 检查是否支持 getUserMedia 方法

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {

// 请求访问摄像头和麦克风

navigator.mediaDevices.getUserMedia({video: true, audio: true})

.then(function (stream) {

// 摄像头和麦克风设备可用

console.log('摄像头和麦克风可用');

})

.catch(function (error) {

// 摄像头和麦克风设备不可用

console.error('摄像头或麦克风不可用', error);

});

} else {

alert('浏览器不支持webRtc');

}

}

</script>

</body>

</html>

js的官方地址:

https://cdn.jsdelivr.net/npm/livekit-client/dist/livekit-client.umd.min.js

我把官方地址复制下来本地使用的。

还有就是eruda.js,这个是可以在手机浏览器上调试的插件,我是下载下来本地使用的,

网上地址:https://cdn.jsdelivr.net/npm/eruda

这里的html需要修改wsURL的地址,也就是把ws://8.218.***.**:7880这个替换成你liveKit的IP,

使用默认端口7880。

然后就是输入你创建的token即可链接livekit了。

如果使用的是ws+ip访问的,只能测试能不能链接成功,不能使用使用视频或者语音。

因为使用视频和语音需要调用麦克风和摄像头,调用摄像头这些则需要域名+SSL证书。

配置成wss的地址。也就是类似这样:wss://gscs.baidu.cn:7443。

申请SSL证书我是在腾讯云申请的,有域名就可以免费申请。

申请后我是用用nginx部署的证书,具体部署的方法这里就不详细说明了。

附上部分:

server {

listen 7443 ssl; #监听的端口

server_name gscs.****.fun;

root html;

index index.html index.htm;

ssl_certificate cert/gscs.****.fun_bundle.pem;

ssl_certificate_key cert/gscs.****.fun.key;

#ssl会话超时时间

ssl_session_timeout 5m;

ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_prefer_server_ciphers on;

location / {

proxy_pass http://8.218.***.**:7880;

proxy_set_header Host $host:$server_port;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

proxy_set_header X-real-ip $remote_addr;

proxy_set_header X-Forwarded-For $remote_addr;

}

}

我这里是单独用7443这个端口作为证书的端口,因为其他地方已经用了443端口了,你也可以使用443,这样访问的时候就不需要单独加上端口。

部署好证书后访问https://gscs.****.fun:7443/,显示ok则代表SSL配置成功。

然后把html里面的wsURL替换成“wss://gscs.****.fun:7443”,即可访问摄像头和语音聊天。

最后附上链接后的网页:

最后如果遇到不能使用摄像头和麦克风的问题:

1、SSL证书的问题,必须使用wss+域名访问liveKit

2、浏览器不支持webRtc,html源码有个checkVideo方法可以验证。不支持就换个浏览器,我测试时就遇到小米浏览器不支持webRtc。

如果有什么问题,欢迎大佬指正。

 最后如果对你有一点点帮助,麻烦支持一下。

全国寄快递5元起,电影票8.8折。更多优惠微信关注公众号:【折价寄件】

感谢阅读!!!!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。