收藏
回答

调用摄像头录制api报错,偶现。

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小程序 Bug wx.createCameraContext 微信iOS客户端 8.0.50 3.5.6

https://developers.weixin.qq.com/miniprogram/dev/component/camera.html

报错截图如下:

报错json内容:

{

"safeAreaInsets": {

"top": 48,

"left": 0,

"right": 0,

"bottom": 34

},

"deviceId": "17261032184623800080",

"appId": "__UNI__F73D08D",

"appName": "阳光朵朵",

"appVersion": "1.1.24",

"appVersionCode": 134,

"appLanguage": "zh-Hans",

"uniCompileVersion": "3.7.4",

"uniRuntimeVersion": "3.7.4",

"uniPlatform": "mp-weixin",

"deviceBrand": "iphone",

"deviceModel": "iPhone 11<iPhone12,1>",

"deviceType": "phone",

"devicePixelRatio": 2,

"deviceOrientation": "portrait",

"osName": "ios",

"osVersion": "17.4.1",

"hostVersion": "8.0.50",

"hostLanguage": "zh-CN",

"hostName": "WeChat",

"hostSDKVersion": "3.5.6",

"hostFontSizeSetting": 17,

"windowTop": 0,

"windowBottom": 0,

"safeArea": {

"bottom": 862,

"height": 814,

"top": 48,

"width": 414,

"left": 0,

"right": 414

},

"fontSizeSetting": 17,

"notificationAuthorized": true,

"locationEnabled": true,

"batteryLevel": 5,

"bluetoothEnabled": false,

"fontSizeScaleFactor": 1,

"version": "8.0.50",

"screenWidth": 414,

"system": "iOS 17.4.1",

"pixelRatio": 2,

"locationAuthorized": true,

"windowHeight": 896,

"model": "iPhone 11<iPhone12,1>",

"phoneCalendarAuthorized": false,

"microphoneEnabled": true,

"wifiEnabled": true,

"bluetoothAuthorized": false,

"memorySize": 3848,

"screenHeight": 896,

"locationReducedAccuracy": false,

"statusBarHeight": 48,

"windowWidth": 414,

"albumAuthorized": true,

"notificationAlertAuthorized": true,

"benchmarkLevel": 34,

"notificationBadgeAuthorized": true,

"language": "zh_CN",

"screenTop": 0,

"notificationSoundAuthorized": true,

"microphoneAuthorized": true,

"cameraAuthorized": true,

"brand": "iPhone",

"platform": "ios",

"SDKVersion": "3.5.6",

"enableDebug": false,

"host": {

"env": "WeChat",

"appId": "",

"version": 402666045

},

"mode": "default"

}

业务代码如下:

import { useRecordStore } from '@/js-sdk/store/record-store';
import { computed, reactive, ref } from 'vue';
import { EventType, SectionType } from '@/js-sdk/enums';
import { showToast } from '@/js-sdk/util/tips';
import { logError, logInfo } from '@/js-sdk/util/log';
import { useVideoStore } from '@/js-sdk/store/video-store';
import { useCameraStore } from '@/js-sdk/store/camera-store';
import AliOss from '@/js-sdk/util/ali-oss';
import { Resource } from '@/js-sdk/typings/typing-api';

export function useNext() {
    const store = useRecordStore();
    const videoStore = useVideoStore();

    function onNext() {
        // eslint-disable-next-line no-async-promise-executor
        return new Promise(async (resolve, reject) => {
            try {
                /**********跳转逻辑,指定下一环节**********/
                store.nextSectionIndex = store.getNextSectionIndex();

                /**********上报当前这个环节打点数据**********/
                store.preventAll = true;
                if (store.sectionStartTime > -1) {
                    store.setTagData(EventType.Stage, {
                        startTime: store.sectionStartTime,
                    });
                }

                /*************处理录制逻辑*************/
                await dealRecord();

                /*************如果不是中止录制也未结束,则直接切换到下一个环节*************/
                if (!store.nextMiddleStop && !store.isFinishedSection) {
                    //切换到下一个环节
                    store.toNextSection();
                    logInfo(`已切换到下一个环节:`, { sectionIndex: store.sectionIndex, sections: store.sections.length });
                    resolve(true);
                    return;
                }

                //记录状态
                store.resolveNext = resolve;
                store.showProgress = store.willRecord && !videoStore.recordFinished;
                store.allSectionDone = true;

                //提交数据(检查数据是否可以提交)
                await store.submitOrderData();
            } catch (err) {
                logError('下一环节发生异常:', err);
                reject(err);
            } finally {
                store.preventAll = false;
            }
        });
    }

    async function dealRecord() {
        const cameraStore = useCameraStore();

        const isLongGame = [SectionType.ReactiveGame, SectionType.ActionRecording].includes(store.nextSection.type);
        const needFinish = cameraStore.willReachLimit || !store.nextSection.needRecording || isLongGame;
        const forceContinue = Date.now() - cameraStore.recordingStartTime < 5000 && !store.isLastRecording;

        //结束录制
        if (cameraStore.recording && needFinish && !forceContinue) {
            logInfo('结束录制开始');
            await cameraStore.stopRecord(store.sectionIndex, false);
            logInfo('结束录制调用成功');
        }

        //开始录制
        const willRecord = !cameraStore.recording && store.nextSection.needRecording;
        if (willRecord) {
            logInfo('调用开始录制');
            await cameraStore.startRecord(store.sectionIndex + 1);
            logInfo('开始录制调用成功');
        }
    }

    return { onNext };
}

export function useGaitRecord(changeNextVideo) {
    const state = reactive({
        recording: 0,
        startTime: 0,
        endTime: 0,
        disabled: false,
    });

    const playBtnText = computed(() => {
        return ['开始', '结束', '重来一次'][state.recording];
    });

    async function onOperate() {
        //开始录制、重新录制
        if (state.recording === 0 || state.recording === 2) {
            changeNextVideo();
            state.startTime = Date.now();
            state.endTime = 0;
            state.recording = 1;
            state.disabled = true;
            setTimeout(() => {
                state.disabled = false;
            }, 5000);
            return;
        }
        //结束录制
        state.endTime = Date.now();
        state.recording = 2;
    }

    function onDisabledTap() {
        showToast('至少录制5秒钟');
    }

    return { playBtnText, state, onOperate, onDisabledTap };
}

export function useDraw() {
    const store = useRecordStore();
    const videoStore = useVideoStore();
    const cameraStore = useCameraStore();

    const signRef = ref(null);
    const isSigned = ref(false);
    const loading = ref(true);
    const disabled = computed(() => {
        return cameraStore.disabled || !isSigned.value;
    });

    //切换环节
    const { onNext } = useNext();

    async function onSubmit() {
        if (store.section.tagType) {
            //上传到oss
            const { tempFilePath } = await signRef.value.save();
            const oss = new AliOss(videoStore.ossConfig);
            const { fileKey } = await oss.uploadImage(tempFilePath);
            store.setTagData(store.section.tagType, {
                startTime: store.sectionStartTime,
                content: fileKey,
            });
        }
        await onNext();
    }

    function onImageLoading(isSuccess) {
        loading.value = false;
        if (!isSuccess) logError(`画板加载失败`, (store.section.resource as Resource).url);
    }

    return { onSubmit, signRef, disabled, isSigned, onImageLoading, loading };
}



import { useRecordStore } from '@/js-sdk/store/record-store'; import { computed, reactive, ref } from 'vue'; import { EventType, SectionType } from '@/js-sdk/enums'; import { showToast } from '@/js-sdk/util/tips'; import { logError, logInfo } from '@/js-sdk/util/log'; import { useVideoStore } from '@/js-sdk/store/video-store'; import { useCameraStore } from '@/js-sdk/store/camera-store'; import AliOss from '@/js-sdk/util/ali-oss'; import { Resource } from '@/js-sdk/typings/typing-api'; export function useNext() { const store = useRecordStore(); const videoStore = useVideoStore(); function onNext() { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { try { /**********跳转逻辑,指定下一环节**********/ store.nextSectionIndex = store.getNextSectionIndex(); /**********上报当前这个环节打点数据**********/ store.preventAll = true; if (store.sectionStartTime > -1) { store.setTagData(EventType.Stage, { startTime: store.sectionStartTime, }); } /*************处理录制逻辑*************/ await dealRecord(); /*************如果不是中止录制也未结束,则直接切换到下一个环节*************/ if (!store.nextMiddleStop && !store.isFinishedSection) { //切换到下一个环节 store.toNextSection(); logInfo(`已切换到下一个环节:`, { sectionIndex: store.sectionIndex, sections: store.sections.length }); resolve(true); return; } //记录状态 store.resolveNext = resolve; store.showProgress = store.willRecord && !videoStore.recordFinished; store.allSectionDone = true; //提交数据(检查数据是否可以提交) await store.submitOrderData(); } catch (err) { logError('下一环节发生异常:', err); reject(err); } finally { store.preventAll = false; } }); } async function dealRecord() { const cameraStore = useCameraStore(); const isLongGame = [SectionType.ReactiveGame, SectionType.ActionRecording].includes(store.nextSection.type); const needFinish = cameraStore.willReachLimit || !store.nextSection.needRecording || isLongGame; const forceContinue = Date.now() - cameraStore.recordingStartTime < 5000 && !store.isLastRecording; //结束录制 if (cameraStore.recording && needFinish && !forceContinue) { logInfo('结束录制开始'); await cameraStore.stopRecord(store.sectionIndex, false); logInfo('结束录制调用成功'); } //开始录制 const willRecord = !cameraStore.recording && store.nextSection.needRecording; if (willRecord) { logInfo('调用开始录制'); await cameraStore.startRecord(store.sectionIndex + 1); logInfo('开始录制调用成功'); } } return { onNext }; } export function useGaitRecord(changeNextVideo) { const state = reactive({ recording: 0, startTime: 0, endTime: 0, disabled: false, }); const playBtnText = computed(() => { return ['开始', '结束', '重来一次'][state.recording]; }); async function onOperate() { //开始录制、重新录制 if (state.recording === 0 || state.recording === 2) { changeNextVideo(); state.startTime = Date.now(); state.endTime = 0; state.recording = 1; state.disabled = true; setTimeout(() => { state.disabled = false; }, 5000); return; } //结束录制 state.endTime = Date.now(); state.recording = 2; } function onDisabledTap() { showToast('至少录制5秒钟'); } return { playBtnText, state, onOperate, onDisabledTap }; } export function useDraw() { const store = useRecordStore(); const videoStore = useVideoStore(); const cameraStore = useCameraStore(); const signRef = ref(null); const isSigned = ref(false); const loading = ref(true); const disabled = computed(() => { return cameraStore.disabled || !isSigned.value; }); //切换环节 const { onNext } = useNext(); async function onSubmit() { if (store.section.tagType) { //上传到oss const { tempFilePath } = await signRef.value.save(); const oss = new AliOss(videoStore.ossConfig); const { fileKey } = await oss.uploadImage(tempFilePath); store.setTagData(store.section.tagType, { startTime: store.sectionStartTime, content: fileKey, }); } await onNext(); } function onImageLoading(isSuccess) { loading.value = false; if (!isSuccess) logError(`画板加载失败`, (store.section.resource as Resource).url); } return { onSubmit, signRef, disabled, isSigned, onImageLoading, loading }; }
回答关注问题邀请回答
收藏

3 个回答

  • 社区技术运营专员--许涛
    社区技术运营专员--许涛
    09-13

    你好,麻烦提供能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)

    09-13
    有用
    回复 4
    • 机器灵磨菜刀
      机器灵磨菜刀
      09-13
      09-13
      回复
    • 机器灵磨菜刀
      机器灵磨菜刀
      09-13
      评论里貌似无法把这个js文件完整的贴出来。
      09-13
      回复
    • 机器灵磨菜刀
      机器灵磨菜刀
      09-13
      09-13
      回复
    • 社区技术运营专员--许涛
      社区技术运营专员--许涛
      09-14回复机器灵磨菜刀
      麻烦提供能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html
      09-14
      回复
  • 那一抹笑😃 穿透阳光
    那一抹笑😃 穿透阳光
    09-13

    你这个不是微信小程序啊

    09-13
    有用
    回复
  • 机器灵磨菜刀
    机器灵磨菜刀
    09-12

    补充一张报错截图:

    09-12
    有用
    回复
登录 后发表内容