微信小程序 录制视频的时候加背景音乐不影响麦克风收音

没想到时隔一年多又掉进了bgm的大坑
这次的需求是用户先选择音乐,然后调起微信的录像api(此处有特殊样式,所以不能直接用选择视频文件录像那个方法),之后将用户拍摄的视频、选择的bgm传给后端,他那边加上水印合成视频返回给前端进行后面的操作。
但是
问题就出在但是
录制视频的时候也要求加上bgm,不然太突兀了,所以就相当于前端这边合成视频和音频,后端再合成水印。

一开始我想的是加个放在页面,录制的时候播放一下,拍好了再播放,假装合成了,其实还是后端去合成。但是用播放音频的话,会影响视频麦克风的收声,录出来的视频只有一两秒有声音

还好及时求助公司大佬,他提出了可以调用全局背景音乐的方法来录制视频
下面展示代码

<page>
    <view class="home">
        <!-- 结果 -->
        <view class="result" wx:if="{{videoSrc}}">
            <video class="video " src="{{videoSrc}}" show-progress="{{false}}" muted='{{false}}' controls="{{true}}"></video>
            <view class="btns">
                <view class="btn" bindtap="initShoot">
                    <img clas='my_img' src='shoot/back.png' />
                </view>
                <view class="btn" bindtap='uploadViedo'>
                    <img clas='my_img' src='shoot/next.png' />
                </view>
            </view>
        </view>
        <!-- 录制 -->
        <view class="duringShoot" wx:else>
            <camera class="mycamera" mode="normal" device-position="front"></camera>
            <view class="tips" wx:if="{{showWord}}">
                <view class="word">
                    <view class="marquee_text" style="left:{{marqueeDistance2}}px">
                        <text>{{text}}</text>
                        <text wx:if="{{marquee2copy_status}}" style="margin-left:{{marquee2_margin}}px;">
                            {{text}}
                        </text>
                    </view>
                </view>
                <view class="icon" bindtap='getsentence'>
                    <img clas='my_img' src='shoot/refresh.png' />
                </view>
            </view>
            <view class="rule" wx:else bindtap="showTips">
                <img clas='my_img' src='shoot/tips.png' />
            </view>
            <view class="countdown" wx:if="{{duringVideo}}">倒计时:{{countdown}}s</view>
            <view class="btns">
                <view class="btn" bindtap="startRecord">
                    <img clas='my_img' src='shoot/btn.png' />
                </view>
                <view class="stop" bindtap="stopRecord" wx:if="{{duringVideo}}">
                    <img clas='my_img' src='shoot/stop.png' />
                </view>
            </view>
        </view>
    </view>
</page>
Page({
    data: {
        //录制
        duringVideo: false,//在录制期间
        countdown: 20,//倒计时
        // 音乐
        audioList: [],//音乐列表
        audioUrl: '',//选中的音乐链接
    },

    onLoad(options) {
        this.getBgms()
        this.ctx = wx.createCameraContext()
        this.setData({
            audioUrl: this.data.audioList[options.index].url,
            soundEnum: this.data.audioList[options.index].enumName
        })
        this.innerAudioContext = wx.createInnerAudioContext({
            useWebAudioImplement: false // 是否使用 WebAudio 作为底层音频驱动,默认关闭。对于短音频、播放频繁的音频建议开启此选项,开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长,因此对于长音频建议关闭此选项
        })
        this.innerAudioContext.src = this.data.audioList[options.index].url
        this.innerAudioContext.loop = true;
    },
    onUnload() {
        clearInterval(this.timer)
        // 
    },
    //获取视频bgm
    getBgms() {
        this.API.Getbgm().then(res => {
            console.log('Getbgmres', res);
            if (res.code == 200) {
                let audioList = res.data
                this.setData({ audioList })
            }
        })
    },
    // --------------录像相关
    // 重新录制
    initShoot() {
        clearInterval(this.timer)
        this.setData({
            showWord: false,
            num: 1,
            src: '',
            videoSrc: '',
            countdown: 20
        })
    },
    startRecord() {
        if (this.data.duringVideo == false) {
            console.log('开始录像');
            this.ctx.startRecord({
                // timeout: 20,
                success: (res) => {
                    console.log('startRecord')
                    clearInterval(this.timer)
                    this.setData({ duringVideo: true, src: '', videoSrc: '', countdown: 20 })
                    this.countdownTime()

                    this.innerAudioContext.play() // 播放
                }
            })
        }
    },
    stopRecord() {
        console.log('结束录像');
        if (this.data.duringVideo == true) {
            wx.showLoading({
                title: '处理中...',
                mask: true
            });
            clearInterval(this.timer)
            this.setData({ duringVideo: false })

            this.ctx.stopRecord({
                compressed: true,
                success: (res) => {
                    console.log('结束录像res', res);
                    wx.hideLoading();
                    this.setData({
                        src: res.tempThumbPath,
                        videoSrc: res.tempVideoPath
                    })
                    this.innerAudioContext.stop() // 播放
                }, fail: (e) => {
                    console.log('fail', e);
                    this.toast('视频录制失败,请重新拍摄~')
                    this.initShoot()
                }
            })
        }
    },
    // 倒计时
    countdownTime() {
        let time = 20
        this.timer = setInterval(() => {
            if (time > 0) {
                time--;
                console.log(time);
                this.setData({ countdown: time })
            } else {
                clearInterval(this.timer)
                this.stopRecord()
            }


        }, 1000);
    },
    // 上传视频
    uploadViedo() {
        wx.showLoading({
            title: '合成中...',
            mask: true
        });
        let file = this.data.videoSrc
        let soundEnum = this.data.soundEnum
        console.log('audioUrl', soundEnum, file);
        //上传单个视频
        this.API.CompoundVideo(soundEnum, file).then(res => {
            console.log('----------res上传视频', res)
            if (res.statusCode == 200) {
                let jsondata = JSON.parse(res.data)
                let videoPath = jsondata.data.videoUrl
                let qrCodeUrl = jsondata.data.qrCodeUrl
                console.log('res.data', res.data);
                wx.navigateTo({
                    url: '/pages/result/result?videoPath=' + videoPath + '&qrCodeUrl=' + qrCodeUrl,
                });
                wx.hideLoading();
            }
        })
    },
    goNext() {
        wx.navigateTo({
            url: '/pages/result/result?videoPath=' + this.data.videoPath + '&qrCodeUrl=' + this.data.qrCodeUrl,
        });
    },
})

核心代码其实是

 this.innerAudioContext = wx.createInnerAudioContext({
            useWebAudioImplement: false // 是否使用 WebAudio 作为底层音频驱动,默认关闭。对于短音频、播放频繁的音频建议开启此选项,开启后将获得更优的性能表现。由于开启此选项后也会带来一定的内存增长,因此对于长音频建议关闭此选项
        })
        this.innerAudioContext.src = this.data.audioList[options.index].url
        this.innerAudioContext.loop = true;

还有就是录制开始的时候调一下this.innerAudioContext.play(),录制结束的时候调一下this.innerAudioContext.stop()

对了 在页面销毁的时候得把背景音乐关掉,不然左滑返回上一页啥的还是会有背景音乐

    onUnload() {
        clearInterval(this.timer)
        clearInterval(this.interval)
        this.innerAudioContext.stop() // 停止
        // 
    },

你可能感兴趣的:(微信小程序,音视频,vue)