123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- const errorMessage = {
- ms1: '请使用微信、Chrome、Firefox或Safari浏览器,如果浏览器没有问题,请联系管理员',
- ms2: '请使用微信、Chrome、Firefox或Safari',
- ms3: 'navigator对象无媒体属性', // 错误提示同ms2
- ms4: '未找到摄像头,请确认摄像头是否正常以及当前摄像头是否被禁用',
- ms5: '检测到当前摄像头已被占用,请关闭摄像头后重新尝试',
- ms6: '摄像头硬件无法满足使用要求,请更换摄像头后重新尝试',
- ms7: '请开启浏览器摄像头权限',
- ms8: '未获取摄像头数据,请检测摄像头是否正常',
- ms9: '当前浏览器不支持,请更换浏览器后尝试',
- ms10: '当前Android系统版本低于9!请更新操作系统',
- ms11: '当前IOS系统版本低于14.3!请更新操作系统',
- ms12: '推荐使用safari浏览器或微信,使用其他浏览器可能会在考试过程中出现摄像头问题,影响考试结果,导致重考,不建议使用其他浏览器。',
- ms13: '推荐使用火狐浏览器、谷歌浏览器或微信,使用其他浏览器可能会在考试过程中出现摄像头问题,影响考试结果,导致重考,不建议使用其他浏览器',
- };
- export {
- errorMessage
- };
- function checkPlatform2() {
- const ua = navigator.userAgent.toLowerCase();
- // 安卓系统
- if (/android/i.test(navigator.userAgent)) {
- let test = /android\s([\w.]+)/;
- let match = test.exec(ua);
- let version = match[1].split('.')[0];
- if (version < 9) {
- Toast.fail(errorMessage.ms10);
- return {
- data: false,
- waitCode: false
- };
- }
- // 判断 浏览器 Android
- if (!checkAndroidForBrowser()) {
- // 提示信息
- Toast.fail({
- message: errorMessage.ms13,
- duration: 5000
- });
- return {
- data: true,
- waitCode: true
- };
- }
- return {
- data: true,
- waitCode: false
- };
- }
- // ios 系统
- if (/(iphone | ipad | ipod | iOS)/i.test(navigator.userAgent)) {
- let test = /os\s([\w]+)/;
- let match = test.exec(ua);
- let vs = match[1].split('_');
- let version = '';
- if (vs.length > 2) {
- version = `${vs[0]}.${vs[1]}`;
- } else if (vs.length == 2) {
- version = `${vs[0]}.${vs[1]}`;
- } else {
- version = `${vs[0]}.0`;
- }
- if (version < 14.3) {
- Toast.fail(errorMessage.ms11);
- return {
- data: false,
- waitCode: false
- };
- }
- // 判断浏览器兼容 判断 ios 浏览器提示信息
- // 判断 浏览器 Android
- if (!checkIosForBrowser()) {
- // 提示信息
- Toast.fail({
- message: errorMessage.ms12,
- duration: 5000
- });
- return {
- data: true,
- waitCode: true
- };
- }
- return {
- data: true,
- waitCode: false
- };
- }
- }
- function checkIosForBrowser() {
- let u = navigator.userAgent;
- let result = false;
- let curname = getBrowser();
- // 如果是 苹果
- if (curname === 'safari') {
- result = true;
- }
- // 如果是 微信
- if (u.indexOf('MicroMessenger') > -1) {
- result = true;
- }
- return result;
- }
- function checkAndroidForBrowser() {
- let curname = getBrowser();
- let result = false;
- // 如果是 谷歌
- if (curname === 'chrome') {
- result = true;
- }
- if (curname === 'firefox') {
- result = true;
- }
- // 如果是 微信
- if (curname === 'wechat') {
- result = true;
- }
- return result;
- }
- function getBrowser() {
- var u = navigator.userAgent;
- var bws = [{
- name: 'sgssapp',
- it: /sogousearch/i.test(u),
- }, {
- name: 'wechat',
- it: /MicroMessenger/i.test(u),
- }, {
- name: 'weibo',
- it: !!u.match(/Weibo/i),
- }, {
- name: 'uc',
- it: !!u.match(/UCBrowser/i) || u.indexOf(' UBrowser') > -1,
- }, {
- name: 'sogou',
- it: u.indexOf('MetaSr') > -1 || u.indexOf('Sogou') > -1,
- }, {
- name: 'xiaomi',
- it: u.indexOf('MiuiBrowser') > -1,
- }, {
- name: 'baidu',
- it: u.indexOf('Baidu') > -1 || u.indexOf('BIDUBrowser') > -1,
- }, {
- name: '360',
- it: u.indexOf('360EE') > -1 || u.indexOf('360SE') > -1,
- }, {
- name: '2345',
- it: u.indexOf('2345Explorer') > -1,
- }, {
- name: 'edge',
- it: u.indexOf('Edge') > -1,
- }, {
- name: 'ie11',
- it: u.indexOf('Trident') > -1 && u.indexOf('rv:11.0') > -1,
- }, {
- name: 'ie',
- it: u.indexOf('compatible') > -1 && u.indexOf('MSIE') > -1,
- }, {
- name: 'firefox',
- it: u.indexOf('Firefox') > -1,
- }, {
- name: 'safari',
- it: u.indexOf('Safari') > -1 && u.indexOf('Chrome') === -1 && u.indexOf('(KHTML, like Gecko) Version') >
- -1 && u.indexOf('MQQBrowser') === -1 && u.indexOf('FingerBrowser') === -1,
- }, {
- name: 'qqbrowser',
- it: u.indexOf('MQQBrowser') > -1 && u.indexOf(' QQ') === -1,
- }, {
- name: 'qq',
- it: u.indexOf('QQ') > -1,
- }, {
- name: 'chrome',
- it: u.indexOf('(KHTML, like Gecko) Chrome') > -1 && u.indexOf('MiuiBrowser') === -1 && u.indexOf(
- 'UCBrowser') === -1 && u.indexOf('HarmonyOS') === -1 && u.indexOf('HuaweiBrowser') === -1,
- }, {
- name: 'opera',
- it: u.indexOf('Opera') > -1 || u.indexOf('OPR') > -1,
- }, {
- name: 'wechat',
- it: /MicroMessenger/i.test(u)
- }, ];
- for (var i = 0; i < bws.length; i++) {
- if (bws[i].it) {
- return bws[i].name;
- }
- }
- return 'other';
- }
- export function errorFunComplete(e) {
- const name = e.name;
- if (name === 'NotFoundError' || name === 'DevicesNotFoundError') {
- Toast.fail(errorMessage.ms4);
- }
- if (name === 'NotReadableError' || name === 'TrackStartError') {
- Toast.fail(errorMessage.ms5);
- } else if (name === 'OverconstrainedError' || name === 'ConstraintNotSatisfiedError') {
- Toast.fail(errorMessage.ms6);
- } else if (name === 'NotAllowedError' || name === 'PermissionDeniedError') {
- Toast.fail(errorMessage.ms7);
- } else if (name === 'TypeError' || name === 'TypeError') {
- Toast.fail(errorMessage.ms8);
- } else {
- Toast.fail(errorMessage.ms9);
- }
- }
- let constraints = {
- audio: false,
- video: {
- width: 480,
- height: 320,
- sourceId: 'default',
- deviceId: 'default',
- transform: 'rotate(180deg)',
- facingMode: {
- // exact: 'user'
- },
- },
- };
- // 校验权限
- export function check(success, error, backFun) {
- if (!navigator) {
- Toast.fail({
- message: errorMessage.ms1,
- duration: 5000
- });
- // 当前浏览器版本 无媒体对象
- backFun && backFun();
- return false;
- }
- const resoutData = checkPlatform2();
- const timeD = resoutData.waitCode ? 5000 : 0;
- if (!resoutData.data) {
- backFun && backFun();
- return false;
- }
- setTimeout(() => {
- if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
- //最新的标准API 返回promise
- navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
- } else if (navigator.webkitGetUserMedia) {
- //webkit核心浏览器
- navigator.webkitGetUserMedia(constraints, success, error);
- } else if (navigator.mozGetUserMedia) {
- //firfox浏览器
- navigator.mozGetUserMedia(constraints, success, error);
- } else if (navigator.getUserMedia) {
- //旧版API
- navigator.getUserMedia(constraints, success, error);
- } else {
- Toast.fail(errorMessage.ms2);
- backFun && backFun();
- }
- }, timeD);
- // 没有媒体对象
- // Toast.fail(errorMessage.ms2);
- // 1. ios 14.3版本一下
- // 2. 当前浏览器非完整版
- }
- // 抓拍确认
- export function check2(success, error) {
- if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
- //最新的标准API 返回promise
- navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
- } else if (navigator.webkitGetUserMedia) {
- //webkit核心浏览器
- navigator.webkitGetUserMedia(constraints, success, error);
- } else if (navigator.mozGetUserMedia) {
- //firfox浏览器
- navigator.mozGetUserMedia(constraints, success, error);
- } else if (navigator.getUserMedia) {
- //旧版API
- navigator.getUserMedia(constraints, success, error);
- }
- }
- import {
- ref,
- nextTick
- } from "vue"
- import {useZhuapaiStore} from "@/store/zhuapai.js"
- import {getFileUpload} from "@/api/kaoshi.js"
- // H5 播放抓拍功能
- export function useH5Camera({
- elVideoId,
- elCanvasId,
- onVideoSuccess, // 成功播放回调
- onVideoError, // 失败回调
- zhuapaiHttp, // 抓拍接口将base64 上传
- operId
- }) {
- const zhuapaiStore = useZhuapaiStore();
- const videoRef = ref('');
- videoRef.value = document.querySelector(`${elVideoId} .uni-video-video`);
- function videoSuccessFun(MediaStream) {
- // 赋值流
- videoRef.value.srcObject = MediaStream;
- // 设置video监听 为了确实获取视频播放判断有视频数据流
- addVideoListener();
- // 播放video 执行播放操作
- playVideo();
- }
- function addVideoListener() {
- videoRef && videoRef.value.addEventListener('play', onVideoPlay);
- }
- function removeVideoListener() {
- videoRef && videoRef.value.removeEventListener('play', onVideoPlay);
- }
- function playVideo() {
- if (videoRef.value) {
- videoRef.value.play();
- }
- }
- function onVideoPlay() {
- onVideoSuccess && onVideoSuccess();
- }
- function videoErrorFun(e) {
- console.log('错误', e)
- removeVideoListener();
- onVideoError && onVideoError(e)
- }
- // 主动开启
- function startH5Camera() {
- check2(videoSuccessFun, videoErrorFun);
- }
- // 主动关闭
- function stopH5Camera() {
- // 重置虚拟流
- const stream = videoRef && videoRef.value.srcObject;
- if (!stream) {
- return;
- }
- const tracks = stream.getTracks();
- tracks.forEach(function(track) {
- track.stop();
- });
- // 销毁视频资源
- videoRef.value.srcObject = null;
- // 移除监听
- removeVideoListener && removeVideoListener();
- }
- function handlePaiZhao() {
- try {
- const streamActive = videoRef.value.srcObject.active;
- // 判断视频流 是否运行
- if (!streamActive) {
- onVideoError && onVideoError(new Error('摄像头抓拍异常'))
- return;
- }
- } catch (e) {
- onVideoError && onVideoError(new Error('摄像头抓拍异常'))
- return;
- }
- try {
- if (zhuapaiStore.status == 0) {
- // status 为 如果抓拍过程中 应用进入后台 传递固定图片 0为正常 1为进入后台
- let canvas = document.querySelector(`${elCanvasId} .uni-canvas-canvas`);
- let context = canvas.getContext('2d');
- context.drawImage(videoRef.value, 0, 0, videoRef.value.clientWidth, videoRef.value.clientHeight);
- const ImageFile = context.canvas.toDataURL('image/png');
- getSnapShotImage(ImageFile);
- } else {
- const ImageFile = getBase64Image()
- getSnapShotImage(ImageFile);
- }
- } catch (err) {
- console.error('源 :绘图失败', err);
- }
- }
- function getBase64Image() {
- var canvas = document.createElement("canvas");
- var ctx = canvas.getContext("2d");
- canvas.width = 480;
- canvas.height = 320;
- ctx.drawImage(document.querySelector('#gdImg'), 0, 0, 480, 320);
- let image = new Image();
- image.src = canvas.toDataURL('image/png', 1)
- setTimeout(res => {
- ctx.clearRect(0, 0, 480, 320)
- }, 500)
- return image.src
- }
- function getSnapShotImage(data) {
- console.log('base64', data)
- const imgData = data.split(';base64,');
- if (!imgData.length) {
- console.error('【源 :拍照数据异常,未找到图片二进制数据分割节点: `;base64,`】');
- return;
- }
- const opt = {
- data: imgData[1],
- prefix: 'kaoshi/zhuapai',
- suffix: 'png',
-
- };
- console.log('optoptopt', opt)
-
- getFileUpload(opt).then(res => {
- const dOption = {
- operId,
- url: res.data
- }
- zhuapaiHttp && zhuapaiHttp(dOption)
- .then(res => {
- console.log('【源 : 获取抓拍数据】');
- })
- .catch(err => {
- console.error('源 :抓拍接口异常', err);
- uni.showToast({
- icon: 'none',
- title: '抓拍图片异常!'
- })
- uni.redirectTo({
- url: "/pages/client/Kaoshi/list"
- })
- });
- }).catch(err => {
- uni.showToast({
- icon: 'none',
- title: '抓拍图片异常!'
- })
- uni.redirectTo({
- url: "/pages/client/Kaoshi/list"
- })
- })
-
-
- }
- return {
- startH5Camera,
- stopH5Camera,
- handlePaiZhao
- }
- }
|