241 lines
4.8 KiB
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> |