new female
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m36s
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m36s
This commit is contained in:
parent
3a8257df5b
commit
fa7c5b7c7a
@ -3,7 +3,7 @@ run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'new_male'
|
- 'new_female'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
BUILD: staging
|
BUILD: staging
|
||||||
@ -30,15 +30,15 @@ jobs:
|
|||||||
uses: https://gitea.yantootech.com/neil/build-push-action@v6
|
uses: https://gitea.yantootech.com/neil/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
push: false
|
push: false
|
||||||
tags: emotion-digital-video:${{ gitea.run_id }}
|
tags: emotion-female-digital-video:${{ gitea.run_id }}
|
||||||
- name: Run docker
|
- name: Run docker
|
||||||
run: |
|
run: |
|
||||||
pwd
|
pwd
|
||||||
if [ "$(docker ps -q -f name=^emotion-digital-video$)" ]; then
|
if [ "$(docker ps -q -f name=^emotion-female-digital-video$)" ]; then
|
||||||
docker stop emotion-digital-video
|
docker stop emotion-female-digital-video
|
||||||
fi
|
fi
|
||||||
docker run -d --rm --name emotion-digital-video \
|
docker run -d --rm --name emotion-female-digital-video \
|
||||||
-v /usr/share/fonts/opentype/noto:/usr/share/fonts \
|
-v /usr/share/fonts/opentype/noto:/usr/share/fonts \
|
||||||
-p 6900:3000 \
|
-p 6901:3000 \
|
||||||
emotion-digital-video:${{ gitea.run_id }}
|
emotion-female-digital-video:${{ gitea.run_id }}
|
||||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
20
server.js
20
server.js
@ -122,24 +122,24 @@ let currentSceneIndex = 0;
|
|||||||
const scenes = [
|
const scenes = [
|
||||||
{
|
{
|
||||||
name: '起床',
|
name: '起床',
|
||||||
defaultVideo: 'qc-bd-4.mp4',
|
defaultVideo: '8-5-qc-bd-female.mp4',
|
||||||
interactionVideo: 'qc-sh-4.mp4',
|
interactionVideo: '8-5-qc-sh-female.mp4',
|
||||||
tag: 'wakeup',
|
tag: 'wakeup',
|
||||||
apiKey: 'bot-20250724150616-xqpz8' // 起床场景的API key
|
apiKey: 'bot-20250730213756-l627w' // 起床场景的API key
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '开车',
|
name: '走路',
|
||||||
defaultVideo: 'kc-bd-3.mp4',
|
defaultVideo: '8-5-sb-bd-female.mp4',
|
||||||
interactionVideo: 'kc-sh-3.mp4',
|
interactionVideo: '8-5-sb-sh-female.mp4',
|
||||||
tag: 'driving',
|
tag: 'driving',
|
||||||
apiKey: 'bot-20250623140339-r8f8b' // 开车场景的API key
|
apiKey: 'bot-20250703161810-sgkrh' // 开车场景的API key
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '喝茶',
|
name: '喝茶',
|
||||||
defaultVideo: 'hc-bd-3.mp4',
|
defaultVideo: '8-5-hc-bd-female.mp4',
|
||||||
interactionVideo: 'hc-sh-3(1).mp4',
|
interactionVideo: '8-5-hc-sh-female.mp4',
|
||||||
tag: 'tea',
|
tag: 'tea',
|
||||||
apiKey: 'bot-20250804180724-4dgtk' // 喝茶场景的API key
|
apiKey: 'bot-20250805140055-ccdr6' // 喝茶场景的API key
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ export const config = {
|
|||||||
// LLM API配置
|
// LLM API配置
|
||||||
llm: {
|
llm: {
|
||||||
apiKey: 'd012651b-a65b-4b13-8ff3-cc4ff3a29783', // 请替换为实际的API密钥
|
apiKey: 'd012651b-a65b-4b13-8ff3-cc4ff3a29783', // 请替换为实际的API密钥
|
||||||
model: 'bot-20250724150616-xqpz8',
|
model: 'bot-20250730213756-l627w',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Minimaxi API配置
|
// Minimaxi API配置
|
||||||
@ -16,7 +16,7 @@ export const config = {
|
|||||||
audio: {
|
audio: {
|
||||||
model: 'speech-02-hd',
|
model: 'speech-02-hd',
|
||||||
voiceSetting: {
|
voiceSetting: {
|
||||||
voice_id: 'yantu-qinggang-demo2-male-4',
|
voice_id: 'yantu-qinggang-3',
|
||||||
speed: 1,
|
speed: 1,
|
||||||
vol: 1,
|
vol: 1,
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
|
|||||||
510
src/index.html
Normal file
510
src/index.html
Normal file
@ -0,0 +1,510 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||||
|
<title>Soulmate In Parallels - 壹和零人工智能</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
<link rel="icon" type="image/png" sizes="48x48" href="favicon.png" />
|
||||||
|
<style>
|
||||||
|
/* 全屏视频样式 */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: linear-gradient(135deg, #87CEEB 0%, #B0E0E6 100%); /* 浅蓝色渐变背景 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
flex: 1;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recorded-video-section {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
/* 确保视频区域固定高度并居中 */
|
||||||
|
min-height: 100vh;
|
||||||
|
max-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 视频容器样式 - 支持双缓冲,固定9:16比例 */
|
||||||
|
.video-container {
|
||||||
|
position: relative;
|
||||||
|
width: 56.25vh; /* 9:16比例,与视频宽度保持一致 */
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 auto; /* 水平居中 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#recordedVideo, #recordedVideoBuffer {
|
||||||
|
position: absolute;
|
||||||
|
width: 56.25vh; /* 9:16比例,高度为100vh时,宽度为100vh * 9/16 = 56.25vh */
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
transition: opacity 0.5s ease-in-out;
|
||||||
|
/* 确保视频始终居中 */
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 主视频默认显示 */
|
||||||
|
#recordedVideo {
|
||||||
|
opacity: 1;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 缓冲视频默认隐藏 */
|
||||||
|
#recordedVideoBuffer {
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 切换状态 */
|
||||||
|
#recordedVideo.switching {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#recordedVideoBuffer.switching {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载状态 */
|
||||||
|
.video-loading {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 10;
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-loading.show {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载动画 */
|
||||||
|
.loading-spinner {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 3px solid rgba(255, 255, 255, 0.3);
|
||||||
|
border-top: 3px solid white;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
margin: 0 auto 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式设计 - 确保在不同屏幕尺寸下视频容器保持9:16比例 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.video-container {
|
||||||
|
height: 100vh;
|
||||||
|
width: 56.25vh; /* 9:16比例,与视频宽度保持一致 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#recordedVideo, #recordedVideoBuffer {
|
||||||
|
width: 56.25vh; /* 9:16比例 */
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
.video-container {
|
||||||
|
height: 100vh;
|
||||||
|
width: 56.25vh; /* 9:16比例,与视频宽度保持一致 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#recordedVideo, #recordedVideoBuffer {
|
||||||
|
width: 56.25vh; /* 9:16比例 */
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 横屏模式优化 */
|
||||||
|
@media (orientation: landscape) and (max-height: 500px) {
|
||||||
|
.video-container {
|
||||||
|
height: 100vh;
|
||||||
|
width: 56.25vh; /* 9:16比例,与视频宽度保持一致 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 竖屏模式优化 */
|
||||||
|
@media (orientation: portrait) {
|
||||||
|
.video-container {
|
||||||
|
height: 100vh;
|
||||||
|
width: 56.25vh; /* 9:16比例,与视频宽度保持一致 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 50px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
z-index: 10;
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: row !important;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保移动端也保持同一行 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.controls {
|
||||||
|
flex-direction: row !important;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(34, 197, 94, 0.9);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 15px rgba(34, 197, 94, 0.3);
|
||||||
|
min-width: auto;
|
||||||
|
padding: 15px 30px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
border-radius: 25px;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton:hover:not(:disabled) {
|
||||||
|
background: rgba(22, 163, 74, 0.95);
|
||||||
|
transform: scale(1.1);
|
||||||
|
box-shadow: 0 6px 20px rgba(34, 197, 94, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton.connecting {
|
||||||
|
background: rgba(255, 193, 7, 0.9);
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton.connecting:hover {
|
||||||
|
background: rgba(255, 193, 7, 0.9);
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton.calling {
|
||||||
|
background: rgba(255, 193, 7, 0.9);
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton.calling:hover {
|
||||||
|
background: rgba(255, 193, 7, 0.95);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
box-shadow: 0 4px 15px rgba(255, 193, 7, 0.3);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
box-shadow: 0 6px 25px rgba(255, 193, 7, 0.6);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
box-shadow: 0 4px 15px rgba(255, 193, 7, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-status {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
color: white;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-status.connecting {
|
||||||
|
background: rgba(255, 193, 7, 0.9);
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-status.connected {
|
||||||
|
background: rgba(40, 167, 69, 0.9);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-status.error {
|
||||||
|
background: rgba(220, 53, 69, 0.9);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton svg {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startButton:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#stopButton {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(220, 53, 69, 0.9);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 15px rgba(220, 53, 69, 0.3);
|
||||||
|
padding: 0; /* 确保没有内边距影响居中 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#stopButton:hover:not(:disabled) {
|
||||||
|
background: rgba(200, 35, 51, 0.95);
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#stopButton svg {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: block; /* 确保SVG作为块级元素 */
|
||||||
|
margin: auto; /* 额外的居中保证 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#stopButton:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 头像样式 - 确保显示 */
|
||||||
|
.avatar-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 15; /* 提高z-index确保在视频上方 */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
opacity: 1; /* 确保默认显示 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-container.hidden {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid rgba(255, 255, 255, 0.8);
|
||||||
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: bold;
|
||||||
|
overflow: hidden; /* 确保图片不会溢出 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block; /* 确保图片显示 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保视频默认隐藏 */
|
||||||
|
#recordedVideo, #recordedVideoBuffer {
|
||||||
|
position: absolute;
|
||||||
|
width: 56.25vh;
|
||||||
|
height: 100vh;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
transition: opacity 0.5s ease-in-out;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
opacity: 0; /* 默认隐藏视频 */
|
||||||
|
z-index: 1; /* 确保在头像下方 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 通话时隐藏头像,显示视频 */
|
||||||
|
.video-container.calling .avatar-container {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container.calling #recordedVideo {
|
||||||
|
opacity: 1;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<!-- 隐藏的header -->
|
||||||
|
<header style="display: none;">
|
||||||
|
<h1>WebRTC 音频通话</h1>
|
||||||
|
<p>实时播放录制视频,支持文本和语音输入</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="main-content">
|
||||||
|
<!-- 音频状态显示 - 完全隐藏 -->
|
||||||
|
<div class="audio-status" style="display: none;">
|
||||||
|
<div class="status-indicator">
|
||||||
|
<span id="audioStatus" style="display: none;">未连接</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 录制视频播放区域 - 全屏显示 -->
|
||||||
|
<div class="recorded-video-section">
|
||||||
|
<div class="video-container" id="videoContainer">
|
||||||
|
<!-- 头像容器 -->
|
||||||
|
<div class="avatar-container" id="avatarContainer">
|
||||||
|
<div class="avatar" id="avatar">
|
||||||
|
<!-- 使用相对路径引用图片 -->
|
||||||
|
<img src="./tx.png" alt="头像" onerror="this.style.display='none'; this.parentElement.innerHTML='AI';">
|
||||||
|
</div>
|
||||||
|
<!-- <div class="avatar-name">AI助手</div> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 主视频元素 -->
|
||||||
|
<video id="recordedVideo" autoplay muted>
|
||||||
|
<source src="" type="video/mp4">
|
||||||
|
您的浏览器不支持视频播放
|
||||||
|
</video>
|
||||||
|
|
||||||
|
<!-- 缓冲视频元素 -->
|
||||||
|
<video id="recordedVideoBuffer" autoplay muted>
|
||||||
|
<source src="" type="video/mp4">
|
||||||
|
您的浏览器不支持视频播放
|
||||||
|
</video>
|
||||||
|
|
||||||
|
<!-- 加载指示器 -->
|
||||||
|
<div class="video-loading" id="videoLoading">
|
||||||
|
<div class="loading-spinner"></div>
|
||||||
|
<div>正在切换视频...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="video-info" style="display: none;">
|
||||||
|
<span id="currentVideoName">未选择视频</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 控制按钮 - 悬浮在视频上方 -->
|
||||||
|
<div class="controls">
|
||||||
|
<button id="startButton" class="btn btn-primary" title="开始通话">
|
||||||
|
<!-- 默认通话图标 -->
|
||||||
|
<svg id="callIcon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
<!-- 通话中文字显示(初始隐藏) -->
|
||||||
|
<span id="callingText" style="display: none; color: white; font-size: 14px;">正在通话中</span>
|
||||||
|
</button>
|
||||||
|
<button id="stopButton" class="btn btn-danger" disabled title="结束通话" style="display: none;">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19.23 15.26l-2.54-.29c-.61-.07-1.21.14-1.64.57l-1.84 1.84c-2.83-1.44-5.15-3.75-6.59-6.59l1.85-1.85c.43-.43.64-1.03.57-1.64l-.29-2.52c-.12-1.01-.97-1.77-1.99-1.77H5.03c-1.13 0-2.07.94-2 2.07.53 8.54 7.36 15.36 15.89 15.89 1.13.07 2.07-.87 2.07-2v-1.73c.01-1.01-.75-1.86-1.76-1.98z" fill="white"/>
|
||||||
|
<line x1="18" y1="6" x2="6" y2="18" stroke="white" stroke-width="2"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 隐藏的输入区域 -->
|
||||||
|
<div class="input-section" style="display: none;">
|
||||||
|
<div class="text-input-group">
|
||||||
|
<input type="text" id="textInput" placeholder="输入文本内容..." />
|
||||||
|
<button id="sendTextButton" class="btn btn-primary">发送文本</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 隐藏的视频选择 -->
|
||||||
|
<div class="video-selection" style="display: none;">
|
||||||
|
<h3>选择要播放的视频</h3>
|
||||||
|
<div id="videoList" class="video-list">
|
||||||
|
<!-- 视频列表将在这里动态生成 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 隐藏的状态显示 -->
|
||||||
|
<div class="status-section" style="display: none;">
|
||||||
|
<div id="connectionStatus" class="status" style="display: none;">未连接</div>
|
||||||
|
<div id="messageLog" class="message-log"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 隐藏的视频元素,用于WebRTC连接 -->
|
||||||
|
<video id="localVideo" autoplay muted playsinline style="display: none;"></video>
|
||||||
|
<video id="remoteVideo" autoplay playsinline style="display: none;"></video>
|
||||||
|
|
||||||
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
|
<script type="module" src="./index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
videos/8-5-hc-bd-female.mp4
Normal file
BIN
videos/8-5-hc-bd-female.mp4
Normal file
Binary file not shown.
BIN
videos/8-5-hc-sh-female.mp4
Normal file
BIN
videos/8-5-hc-sh-female.mp4
Normal file
Binary file not shown.
BIN
videos/8-5-qc-bd-female.mp4
Normal file
BIN
videos/8-5-qc-bd-female.mp4
Normal file
Binary file not shown.
BIN
videos/8-5-qc-sh-female.mp4
Normal file
BIN
videos/8-5-qc-sh-female.mp4
Normal file
Binary file not shown.
BIN
videos/8-5-sb-bd-female.mp4
Normal file
BIN
videos/8-5-sb-bd-female.mp4
Normal file
Binary file not shown.
BIN
videos/8-5-sb-sh-female.mp4
Normal file
BIN
videos/8-5-sb-sh-female.mp4
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user