hldy_app_mini/pages/recording/recorder.vue

241 lines
4.8 KiB
Vue

<!-- SimpleRecorder.vue -->
<template>
<view class="simple-recorder">
<!-- 录制按钮 -->
<view
class="simple-record-btn"
:class="{ 'recording': isRecording }"
@click="toggleRecording"
>
<view class="btn-icon">
<view v-if="!isRecording" class="icon-start">●</view>
<view v-else class="icon-stop">■</view>
</view>
<text class="btn-text">
{{ isRecording ? '停止录制' : '开始录制' }}
</text>
</view>
<!-- 录制时间 -->
<view v-if="isRecording" class="recording-time">
<text>{{ formatTime(recordTime) }}</text>
</view>
<!-- 状态提示 -->
<view v-if="message" class="status-message">
<text>{{ message }}</text>
</view>
</view>
</template>
<script>
import { getScreenRecorder } from './recorder.js'
export default {
data() {
return {
recorder: null,
isRecording: false,
recordTime: 0,
recordTimer: null,
message: ''
}
},
onLoad() {
this.initRecorder()
},
onUnload() {
this.cleanup()
},
methods: {
// 初始化
async initRecorder() {
try {
this.recorder = getScreenRecorder()
await this.recorder.startListen()
console.log('录屏器初始化成功')
} catch (error) {
console.error('初始化失败:', error)
this.showMessage('录屏功能初始化失败' + error)
}
},
// 开始/停止录制
async toggleRecording() {
if (this.isRecording) {
await this.stopRecord()
} else {
await this.startRecord()
}
},
// 开始录制
async startRecord() {
try {
this.showMessage('开始录制...')
const options = {
width: 1280,
height: 720,
bitRate: 4000000,
recordAudio: true
}
await this.recorder.start(options)
this.isRecording = true
this.recordTime = 0
this.startTimer()
this.showMessage('录制已开始')
} catch (error) {
console.error('开始录制失败:', error)
this.showMessage('开始录制失败: ' + error.message)
}
},
// 停止录制
async stopRecord() {
try {
this.showMessage('停止录制...')
await this.recorder.stop()
this.isRecording = false
this.stopTimer()
this.showMessage('录制已停止')
} catch (error) {
console.error('停止录制失败:', error)
this.showMessage('停止录制失败: ' + error.message)
}
},
// 计时器
startTimer() {
this.stopTimer()
this.recordTimer = setInterval(() => {
this.recordTime++
}, 1000)
},
stopTimer() {
if (this.recordTimer) {
clearInterval(this.recordTimer)
this.recordTimer = null
}
},
// 格式化时间
formatTime(seconds) {
const minutes = Math.floor(seconds / 60)
const secs = seconds % 60
return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
},
// 显示消息
showMessage(msg) {
this.message = msg
setTimeout(() => {
this.message = ''
}, 3000)
},
// 清理
cleanup() {
this.stopTimer()
if (this.recorder) {
this.recorder.destroy()
}
}
}
}
</script>
<style>
.simple-recorder {
padding: 100rpx 30rpx;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
background: #f5f5f5;
}
.simple-record-btn {
width: 200rpx;
height: 200rpx;
border-radius: 50%;
background: #ff3b30;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 40rpx;
box-shadow: 0 10rpx 30rpx rgba(255, 59, 48, 0.3);
transition: all 0.3s ease;
}
.simple-record-btn.recording {
background: #007AFF;
box-shadow: 0 10rpx 30rpx rgba(0, 122, 255, 0.3);
transform: scale(1.1);
}
.btn-icon {
width: 100rpx;
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
}
.icon-start {
color: white;
font-size: 80rpx;
line-height: 1;
}
.icon-stop {
color: white;
font-size: 60rpx;
line-height: 1;
}
.btn-text {
color: white;
font-size: 28rpx;
font-weight: bold;
}
.recording-time {
font-size: 36rpx;
color: #333;
font-family: monospace;
font-weight: bold;
margin-top: 20rpx;
padding: 20rpx 40rpx;
background: white;
border-radius: 50rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
}
.status-message {
position: fixed;
bottom: 100rpx;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 20rpx 40rpx;
border-radius: 50rpx;
font-size: 28rpx;
z-index: 1000;
}
</style>