hejianhao
3 天以前 04e2948d80d575bb273363264de7d52219538331
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<template>
    <view class="recorder">
    </view>
</template>
 
<script>
    export default {
        data() {
            return {
                isUserMedia: false,
                stream: null,
                audio: null,
                recorder: null,
                chunks: [],
                startTime: 0
            }
        },
        mounted() {
            /**
             *     error 事件的返回状态
             *     100: 请在HTTPS环境中使用
             *     101: 浏览器不支持
             *  201: 用户拒绝授权
             *  500: 未知错误
             * */
            if (origin.indexOf('https') === -1) {
                this.$emit('error', '100')
                throw '请在 https 环境中使用本插件。'
            }
            if (!navigator.mediaDevices || !window.MediaRecorder) {
                this.$emit('error', '101')
                throw '当前浏览器不支持'
            }
 
            this.getRecorderManager()
        },
        methods: {
            getRecorderManager() {
                this.audio = document.createElement('audio')
                navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
                    this.isUserMedia = true
                    stream.getTracks().forEach((track) => {
                        track.stop()
                    })
                }).catch(err => {
                    this.onErrorHandler(err)
                })
            },
            start() {
                if (!this.isUserMedia) return console.log('设备不支持')
 
                navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
                    this.startTime = new Date().getTime()
                    this.stream = stream
                    this.recorder = new MediaRecorder(stream)
                    this.recorder.ondataavailable = this.getRecordingData
                    this.recorder.onstop = this.saveRecordingData
                    this.recorder.start()
                }).catch(err => {
                    this.onErrorHandler(err)
                })
            },
            stop() {
                this.recorder.stop()
                this.stream.getTracks().forEach((track) => {
                    track.stop()
                })
            },
            getRecordingData(e) {
                this.chunks.push(e.data)
            },
            saveRecordingData() {
                const blob = new Blob(this.chunks, { 'type': 'audio/mpeg' }),
                    localUrl = URL.createObjectURL(blob)
 
                const endTime = new Date().getTime()
 
                let duration = (endTime - this.startTime).toString().split('')
                duration.splice(duration.length - 2)
                duration.splice(duration.length - 1, 0, '.')
                duration = parseFloat(duration.join(''))
 
                const recorder = {
                    data: blob,
                    duration: duration,
                    localUrl: localUrl
                }
                this.$emit('success', recorder)
            },
            onErrorHandler(err) {
                console.log(err)
                if (err.name === 'NotAllowedError') {
                    this.$emit('error', '201')
                    throw '用户拒绝了当前的浏览器实例的访问请求'
                }
 
                if (err.name === 'NotReadableError') {
                    this.$emit('error', '101')
                    throw '当前浏览器不支持'
                }
 
                this.$emit('error', '500')
                throw '调用失败,原因不详'
 
            }
        },
        destroyed() {
            this.stop()
        }
    }
</script>
<style>
</style>