321
This commit is contained in:
parent
04c3df3f05
commit
6718eed4e4
|
|
@ -249,6 +249,10 @@
|
|||
@section Scripts {
|
||||
<script src="~/lib/microsoft-signalr/signalr.min.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
||||
<script src='https://web.sdk.qcloud.com/trtc/webrtc/v5/dist/trtc.js'></script>
|
||||
<script src="~//js/lib-generate-test-usersig.min.js"></script>
|
||||
<script src="~//js/generateTestUserSig.js"></script>
|
||||
<script>
|
||||
let connection = null;
|
||||
let refreshDisplayInterval = null;
|
||||
|
|
@ -269,6 +273,36 @@
|
|||
let currentVolume = 1.0; // 默认音量
|
||||
let volumeBoost = 3.0; // 音量增益倍数,提高接收到的音频音量
|
||||
|
||||
const sdkAppId = 1600079538;
|
||||
const sdkSecretKey = "df2427757c0ec29ae8ca45611ddb70381144d55338e5ac73c2da27a9c32729f6";
|
||||
let userId = "监听者:" + Math.random().toString(36).substring(2, 15);
|
||||
let roomId = 8888;
|
||||
|
||||
let trtc = TRTC.create();
|
||||
|
||||
async function enterRoom() {
|
||||
try {
|
||||
trtc = TRTC.create();
|
||||
// 生成用户签名
|
||||
const { userSig } = genTestUserSig({ sdkAppId, userId, sdkSecretKey });
|
||||
// 进入房间
|
||||
await trtc.enterRoom({ sdkAppId, userId, userSig, roomId: roomId });
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function leaveRoom() {
|
||||
try {
|
||||
await trtc.exitRoom();
|
||||
trtc.destroy();
|
||||
// 更新状态指示器为红色(已断开)
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 调试日志
|
||||
function log(message) {
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
|
|
@ -489,12 +523,7 @@
|
|||
updateCallStatus(true);
|
||||
return;
|
||||
}
|
||||
if (isAudioStreamEnabled && callInProgress) {
|
||||
// 确保音频流开启且通话进行中
|
||||
log("接收到实时音频数据...");
|
||||
// 直接传递原始数据,让playRealTimeAudio函数内部处理
|
||||
playRealTimeAudio(audioData);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 音频流设置更新消息
|
||||
|
|
@ -539,6 +568,7 @@
|
|||
// 当检测到新通话时,先显示确认对话框
|
||||
const confirmDialog = new bootstrap.Modal(document.getElementById('callConfirmDialog'));
|
||||
confirmDialog.show();
|
||||
enterRoom();
|
||||
return; // 等待用户确认后再继续处理
|
||||
} else {
|
||||
const indicator = document.getElementById("status-indicator");
|
||||
|
|
@ -550,6 +580,7 @@
|
|||
const confirmDialog = bootstrap.Modal.getInstance(document.getElementById('callConfirmDialog'));
|
||||
if (confirmDialog) {
|
||||
confirmDialog.hide();
|
||||
exitRoom();
|
||||
log("通话已结束,自动关闭确认对话框");
|
||||
}
|
||||
}
|
||||
|
|
@ -1651,7 +1682,7 @@
|
|||
// 从小端字节序读取16位整数
|
||||
for (let i = 0; i < pcmData.length; i += 2) {
|
||||
if (i + 1 < pcmData.length) {
|
||||
int16Data[i/2] = dataView.getInt16(i, true); // true表示小端字节序
|
||||
int16Data[i / 2] = dataView.getInt16(i, true); // true表示小端字节序
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
|
@ -1666,7 +1697,7 @@
|
|||
int16Data = new Int16Array(pcmData.length / 2);
|
||||
for (let i = 0; i < pcmData.length; i += 2) {
|
||||
if (i + 1 < pcmData.length) {
|
||||
int16Data[i/2] = dataView.getInt16(i, true);
|
||||
int16Data[i / 2] = dataView.getInt16(i, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
|
||||
<PackageReference Include="NAudio" Version="2.2.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
|
|
|
|||
Binary file not shown.
7
ShengShengBuXi/wwwroot/js/clipboard.min.js
vendored
Normal file
7
ShengShengBuXi/wwwroot/js/clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
23
ShengShengBuXi/wwwroot/js/generateTestUserSig.js
Normal file
23
ShengShengBuXi/wwwroot/js/generateTestUserSig.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* eslint-disable*/
|
||||
|
||||
function genTestUserSig({ sdkAppId, userId, sdkSecretKey }) {
|
||||
|
||||
const SDKAPPID = sdkAppId;
|
||||
|
||||
const EXPIRETIME = 604800;
|
||||
|
||||
const SDKSECRETKEY = sdkSecretKey;
|
||||
|
||||
// a soft reminder to guide developer to configure sdkAppId/SDKSecretKey
|
||||
if (SDKAPPID === '' || SDKSECRETKEY === '') {
|
||||
alert(
|
||||
'Please configure your SDKAPPID/SDKSECRETKEY in js/debug/GenerateTestUserSig.js'
|
||||
);
|
||||
}
|
||||
const generator = new LibGenerateTestUserSig(SDKAPPID, SDKSECRETKEY, EXPIRETIME);
|
||||
const userSig = generator.genTestUserSig(userId);
|
||||
return {
|
||||
sdkAppId: SDKAPPID,
|
||||
userSig: userSig
|
||||
};
|
||||
}
|
||||
2
ShengShengBuXi/wwwroot/js/lib-generate-test-usersig.min.js
vendored
Normal file
2
ShengShengBuXi/wwwroot/js/lib-generate-test-usersig.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
243
ShengShengBuXi/wwwroot/test.html
Normal file
243
ShengShengBuXi/wwwroot/test.html
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WebSocket 音频播放器</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Microsoft YaHei', Arial, sans-serif;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-top: 0;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
margin: 20px 0;
|
||||
background-color: #e0e0e0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.status-text {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.red {
|
||||
background-color: #ff5252;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
background-color: #FFC107;
|
||||
}
|
||||
|
||||
#status {
|
||||
padding: 10px 15px;
|
||||
border-radius: 4px;
|
||||
background-color: #f0f0f0;
|
||||
margin: 15px 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#audioPlayer {
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-top: 20px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px 24px;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
background-color: #cccccc;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>WebSocket 音频播放器</h1>
|
||||
|
||||
<div id="statusIndicator" class="status-indicator red">
|
||||
<span class="status-text">未连接</span>
|
||||
</div>
|
||||
|
||||
<div id="status">等待连接...</div>
|
||||
|
||||
<audio id="audioPlayer" controls></audio>
|
||||
|
||||
<div class="controls">
|
||||
<button id="connectBtn">连接WebSocket</button>
|
||||
<button id="clearBtn">清空数据</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const statusDiv = document.getElementById('status');
|
||||
const audioPlayer = document.getElementById('audioPlayer');
|
||||
const connectBtn = document.getElementById('connectBtn');
|
||||
const clearBtn = document.getElementById('clearBtn');
|
||||
const statusIndicator = document.getElementById('statusIndicator');
|
||||
const statusText = statusIndicator.querySelector('.status-text');
|
||||
|
||||
let ws = null;
|
||||
|
||||
// 使用Blob方式处理音频数据
|
||||
let audioBlobs = [];
|
||||
|
||||
function connectWebSocket() {
|
||||
// 清空之前的数据
|
||||
audioBlobs = [];
|
||||
statusDiv.textContent = "正在连接...";
|
||||
statusIndicator.className = "status-indicator yellow";
|
||||
statusText.textContent = "连接中";
|
||||
|
||||
// 创建WebSocket连接
|
||||
ws = new WebSocket("ws://localhost:81/ws");
|
||||
ws.binaryType = "arraybuffer"; // 指定二进制数据类型
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log("WebSocket 已连接");
|
||||
statusDiv.textContent = "已连接,等待音频数据...";
|
||||
connectBtn.textContent = "断开连接";
|
||||
statusIndicator.className = "status-indicator green";
|
||||
statusText.textContent = "已连接";
|
||||
};
|
||||
|
||||
ws.onmessage = (event) => {
|
||||
// 确保我们收到的是ArrayBuffer
|
||||
if (event.data instanceof ArrayBuffer) {
|
||||
// 创建Blob对象
|
||||
const blob = new Blob([event.data], { type: 'audio/ogg; codecs=opus' });
|
||||
audioBlobs.push(blob);
|
||||
|
||||
// 创建包含所有数据的完整Blob
|
||||
const fullBlob = new Blob(audioBlobs, { type: 'audio/ogg; codecs=opus' });
|
||||
|
||||
// 更新状态显示
|
||||
statusDiv.textContent = `接收到音频数据: 共 ${audioBlobs.length} 个数据块`;
|
||||
|
||||
// 更新音频播放源
|
||||
const audioUrl = URL.createObjectURL(fullBlob);
|
||||
|
||||
// 记住当前播放位置
|
||||
const currentTime = audioPlayer.currentTime;
|
||||
const wasPlaying = !audioPlayer.paused;
|
||||
|
||||
audioPlayer.src = audioUrl;
|
||||
|
||||
// 如果正在播放,恢复播放状态和位置
|
||||
if (wasPlaying) {
|
||||
audioPlayer.currentTime = currentTime;
|
||||
audioPlayer.play().catch(e => console.error("播放错误:", e));
|
||||
}
|
||||
} else {
|
||||
console.warn("收到非二进制数据:", event.data);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log("WebSocket 连接关闭");
|
||||
statusDiv.textContent = "连接已关闭";
|
||||
connectBtn.textContent = "连接WebSocket";
|
||||
statusIndicator.className = "status-indicator red";
|
||||
statusText.textContent = "未连接";
|
||||
};
|
||||
|
||||
ws.onerror = (error) => {
|
||||
console.error("WebSocket 错误:", error);
|
||||
statusDiv.textContent = "连接错误";
|
||||
connectBtn.textContent = "重新连接";
|
||||
statusIndicator.className = "status-indicator red";
|
||||
statusText.textContent = "连接错误";
|
||||
};
|
||||
}
|
||||
|
||||
connectBtn.addEventListener('click', () => {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
ws.close();
|
||||
} else {
|
||||
connectWebSocket();
|
||||
}
|
||||
});
|
||||
|
||||
clearBtn.addEventListener('click', () => {
|
||||
audioBlobs = [];
|
||||
audioPlayer.src = "";
|
||||
statusDiv.textContent = "数据已清空";
|
||||
});
|
||||
|
||||
// 初始连接
|
||||
connectWebSocket();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
187
ShengShengBuXi/wwwroot/zhibo.html
Normal file
187
ShengShengBuXi/wwwroot/zhibo.html
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>录音</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Microsoft YaHei', Arial, sans-serif;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
margin: 20px 0 40px;
|
||||
background-color: #e0e0e0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.status-text {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.red {
|
||||
background-color: #ff5252;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px 24px;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#start {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
|
||||
#stop {
|
||||
background-color: #f44336;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="title">实时音频录制</h1>
|
||||
|
||||
<div id="statusIndicator" class="status-indicator red">
|
||||
<span class="status-text">未连接</span>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button id="start" onclick="enterRoom()">启动直播</button>
|
||||
<button id="stop" onclick="leaveRoom()">关闭直播</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
||||
<!-- <script src="https://www.unpkg.com/trtc-sdk-v5@5.9.1/trtc.js"></script> -->
|
||||
<script src='https://web.sdk.qcloud.com/trtc/webrtc/v5/dist/trtc.js'></script>
|
||||
<script src="/js/lib-generate-test-usersig.min.js"></script>
|
||||
<script src="/js/generateTestUserSig.js"></script>
|
||||
<script>
|
||||
/* eslint-disable*/
|
||||
const sdkAppId = 1600079538;
|
||||
const sdkSecretKey = "df2427757c0ec29ae8ca45611ddb70381144d55338e5ac73c2da27a9c32729f6";
|
||||
let userId = "主播";
|
||||
let roomId = 8888;
|
||||
|
||||
const statusIndicator = document.getElementById('statusIndicator');
|
||||
const statusText = statusIndicator.querySelector('.status-text');
|
||||
|
||||
let trtc = TRTC.create();
|
||||
|
||||
async function enterRoom() {
|
||||
try {
|
||||
trtc = TRTC.create();
|
||||
// 更新状态指示器为过渡状态
|
||||
statusIndicator.style.backgroundColor = '#FFC107';
|
||||
statusText.textContent = '连接中...';
|
||||
|
||||
// 生成用户签名
|
||||
const { userSig } = genTestUserSig({ sdkAppId, userId, sdkSecretKey });
|
||||
|
||||
// 进入房间
|
||||
await trtc.enterRoom({ sdkAppId, userId, userSig, roomId: roomId });
|
||||
|
||||
// 开启本地音频
|
||||
await trtc.startLocalAudio();
|
||||
|
||||
// 更新状态指示器为绿色(已连接)
|
||||
statusIndicator.className = 'status-indicator green';
|
||||
statusText.textContent = '直播中';
|
||||
|
||||
// 禁用启动按钮
|
||||
document.getElementById('start').disabled = true;
|
||||
|
||||
} catch (error) {
|
||||
console.error('进入房间失败:', error);
|
||||
statusIndicator.className = 'status-indicator red';
|
||||
statusText.textContent = '连接失败';
|
||||
}
|
||||
}
|
||||
|
||||
async function leaveRoom() {
|
||||
try {
|
||||
await trtc.exitRoom();
|
||||
trtc.destroy();
|
||||
// 更新状态指示器为红色(已断开)
|
||||
statusIndicator.className = 'status-indicator red';
|
||||
statusText.textContent = '未连接';
|
||||
|
||||
// 启用启动按钮
|
||||
document.getElementById('start').disabled = false;
|
||||
|
||||
} catch (error) {
|
||||
console.error('离开房间失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
// 初始化时设置状态
|
||||
statusIndicator.className = 'status-indicator red';
|
||||
statusText.textContent = '未连接';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
187
ShengShengBuXi/wwwroot/zhibo1.html
Normal file
187
ShengShengBuXi/wwwroot/zhibo1.html
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>录音</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Microsoft YaHei', Arial, sans-serif;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
margin: 20px 0 40px;
|
||||
background-color: #e0e0e0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.status-text {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.red {
|
||||
background-color: #ff5252;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px 24px;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#start {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
|
||||
#stop {
|
||||
background-color: #f44336;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="title">实时音频录制</h1>
|
||||
|
||||
<div id="statusIndicator" class="status-indicator red">
|
||||
<span class="status-text">未连接</span>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button id="start" onclick="enterRoom()">启动直播</button>
|
||||
<button id="stop" onclick="leaveRoom()">关闭直播</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
||||
<!-- <script src="https://www.unpkg.com/trtc-sdk-v5@5.9.1/trtc.js"></script> -->
|
||||
<script src='https://web.sdk.qcloud.com/trtc/webrtc/v5/dist/trtc.js'></script>
|
||||
<script src="/js/lib-generate-test-usersig.min.js"></script>
|
||||
<script src="/js/generateTestUserSig.js"></script>
|
||||
<script>
|
||||
|
||||
const statusIndicator = document.getElementById('statusIndicator');
|
||||
const statusText = statusIndicator.querySelector('.status-text');
|
||||
/* eslint-disable*/
|
||||
const sdkAppId = 1600079538;
|
||||
const sdkSecretKey = "df2427757c0ec29ae8ca45611ddb70381144d55338e5ac73c2da27a9c32729f6";
|
||||
let userId = "监听者:" + Math.random().toString(36).substring(2, 15);
|
||||
let roomId = 8888;
|
||||
|
||||
let trtc = TRTC.create();
|
||||
|
||||
async function enterRoom() {
|
||||
try {
|
||||
trtc = TRTC.create();
|
||||
// 更新状态指示器为过渡状态
|
||||
statusIndicator.style.backgroundColor = '#FFC107';
|
||||
statusText.textContent = '连接中...';
|
||||
|
||||
// 生成用户签名
|
||||
const { userSig } = genTestUserSig({ sdkAppId, userId, sdkSecretKey });
|
||||
|
||||
// 进入房间
|
||||
await trtc.enterRoom({ sdkAppId, userId, userSig, roomId: roomId });
|
||||
|
||||
// // 开启本地音频
|
||||
// await trtc.startLocalAudio();
|
||||
|
||||
// 更新状态指示器为绿色(已连接)
|
||||
statusIndicator.className = 'status-indicator green';
|
||||
statusText.textContent = '通话中';
|
||||
|
||||
// 禁用启动按钮
|
||||
document.getElementById('start').disabled = true;
|
||||
|
||||
} catch (error) {
|
||||
console.error('进入房间失败:', error);
|
||||
statusIndicator.className = 'status-indicator red';
|
||||
statusText.textContent = '连接失败';
|
||||
}
|
||||
}
|
||||
|
||||
async function leaveRoom() {
|
||||
try {
|
||||
await trtc.exitRoom();
|
||||
trtc.destroy();
|
||||
// 更新状态指示器为红色(已断开)
|
||||
statusIndicator.className = 'status-indicator red';
|
||||
statusText.textContent = '未连接';
|
||||
|
||||
// 启用启动按钮
|
||||
document.getElementById('start').disabled = false;
|
||||
|
||||
} catch (error) {
|
||||
console.error('离开房间失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
// 初始化时设置状态
|
||||
statusIndicator.className = 'status-indicator red';
|
||||
statusText.textContent = '未连接';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Loading…
Reference in New Issue
Block a user