video plus
This commit is contained in:
parent
ed8da6cde9
commit
42c1b64a99
@ -1,39 +1,25 @@
|
||||
<template>
|
||||
<div class="emojiRoot">
|
||||
<div
|
||||
@click="() => photoActionsSelect(0)"
|
||||
class="flex flex-col items-center"
|
||||
>
|
||||
<div
|
||||
class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"
|
||||
>
|
||||
<div @click="() => photoActionsSelect(0)" class="flex flex-col items-center">
|
||||
<div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center">
|
||||
<tm-image :width="53" :height="44" :src="photoAlbum"></tm-image>
|
||||
</div>
|
||||
<div class="mt-[6rpx] text-[#666666] text-[24rpx]">照片</div>
|
||||
</div>
|
||||
<div
|
||||
@click="() => photoActionsSelect(1)"
|
||||
class="flex flex-col items-center"
|
||||
>
|
||||
<div
|
||||
class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"
|
||||
>
|
||||
<div @click="() => photoActionsSelect(1)" class="flex flex-col items-center">
|
||||
<div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center">
|
||||
<tm-image :width="53" :height="44" :src="videoImg"></tm-image>
|
||||
</div>
|
||||
<div class="mt-[6rpx] text-[#666666] text-[24rpx]">视频</div>
|
||||
</div>
|
||||
<div @click="takePhoto" class="flex flex-col items-center">
|
||||
<div
|
||||
class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"
|
||||
>
|
||||
<div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center">
|
||||
<tm-image :width="53" :height="44" :src="photoGraph"></tm-image>
|
||||
</div>
|
||||
<div class="mt-[6rpx] text-[#666666] text-[24rpx]">拍摄</div>
|
||||
</div>
|
||||
<div @click="chooseFile" class="flex flex-col items-center">
|
||||
<div
|
||||
class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center"
|
||||
>
|
||||
<div class="w-[106rpx] h-[106rpx] bg-[#F9F9F9] rounded-[60rpx] flex-center">
|
||||
<tm-image :width="53" :height="44" :src="folder"></tm-image>
|
||||
</div>
|
||||
<div class="mt-[6rpx] text-[#666666] text-[24rpx]">文件</div>
|
||||
@ -72,7 +58,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
base64Url: ''
|
||||
base64Url: '',
|
||||
})
|
||||
|
||||
const uploadsStore = useUploadsStore()
|
||||
@ -92,8 +78,9 @@ const onProgressFn = (progress, id) => {
|
||||
updateUploadProgress(id, (progress.loaded / progress.total) * 100)
|
||||
}
|
||||
|
||||
const photoActionsSelect = (index) => {
|
||||
const photoActionsSelect = async (index) => {
|
||||
if (index === 0) {
|
||||
if (typeof plus === 'undefined') {
|
||||
uni.chooseImage({
|
||||
sourceType: ['album'],
|
||||
count: 9,
|
||||
@ -106,22 +93,211 @@ const photoActionsSelect = (index) => {
|
||||
},
|
||||
})
|
||||
} else {
|
||||
uni.chooseVideo({
|
||||
sourceType: ['album'],
|
||||
success: async (res) => {
|
||||
plus?.gallery.pick(
|
||||
(res) => {
|
||||
console.log(res, 'res')
|
||||
let data = await onUploadImageVideo(
|
||||
res.tempFile,
|
||||
'video',
|
||||
res.tempFilePath,
|
||||
)
|
||||
res.files.reverse()
|
||||
res.files.forEach(async (filePath) => {
|
||||
plus?.io?.resolveLocalFileSystemURL(
|
||||
filePath,
|
||||
async (entry) => {
|
||||
entry.file((file) => {
|
||||
const fileReader = new plus.io.FileReader()
|
||||
fileReader.readAsDataURL(file)
|
||||
fileReader.onloadend = async (e) => {
|
||||
const base64Url = e.target.result
|
||||
const fileObj = base64ToFile(base64Url)
|
||||
let data = await onUploadImageVideo(fileObj, 'image')
|
||||
emit('selectImg', data, data.file_num)
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
(err) => {
|
||||
console.log(err)
|
||||
},
|
||||
)
|
||||
})
|
||||
},
|
||||
(err) => {
|
||||
console.log(err)
|
||||
},
|
||||
{
|
||||
filter: 'image',
|
||||
maximum: 9,
|
||||
multiple: true,
|
||||
onmaxed: () => {
|
||||
plus.nativeUI.toast('最多只能选择9张图片')
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// uni.chooseVideo({
|
||||
// sourceType: ['album'],
|
||||
// compressed: true,
|
||||
// maxDuration: 60,
|
||||
// success: async (res) => {
|
||||
// console.log( 'chooseVideo res.tempFilePath',res.tempFilePath)
|
||||
// console.log( 'chooseVideo res.tempFile',res.tempFile)
|
||||
// return
|
||||
// let data = await onUploadImageVideo(
|
||||
// res.tempFile,
|
||||
// 'video',
|
||||
// res.tempFilePath,
|
||||
// )
|
||||
// emit('selectImg', data, data.file_num)
|
||||
// },
|
||||
// })
|
||||
|
||||
plus?.gallery.pick(
|
||||
(res) => {
|
||||
res.files.reverse()
|
||||
res.files.forEach(async (filePath) => {
|
||||
plus?.io?.resolveLocalFileSystemURL(
|
||||
filePath,
|
||||
async (entry) => {
|
||||
entry.file(async (file) => {
|
||||
|
||||
try {
|
||||
console.log('filePath', filePath)
|
||||
// 获取文件内容并创建 Blob URL
|
||||
playVideoWithNativeBridge(filePath)
|
||||
const videoInfo = await getVideoInfo(filePath);
|
||||
console.log('视频信息:', videoInfo);
|
||||
|
||||
console.log('文件详细信息:', {
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
});
|
||||
const fileInfo = await getFilePath(file);
|
||||
console.log('fileInfo', fileInfo)
|
||||
|
||||
// 继续处理上传逻辑
|
||||
let data = await onUploadImageVideo(file, 'video', videoInfo);
|
||||
emit('selectImg', data, data.file_num);
|
||||
} catch (error) {
|
||||
console.log('文件处理失败:', error);
|
||||
}
|
||||
})
|
||||
},
|
||||
(err) => {
|
||||
console.log(err)
|
||||
},
|
||||
)
|
||||
})
|
||||
},
|
||||
(err) => {
|
||||
console.log(err)
|
||||
},
|
||||
{
|
||||
filter: 'video',
|
||||
maximum: 2,
|
||||
multiple: true,
|
||||
onmaxed: () => {
|
||||
plus.nativeUI.toast('最多只能选择2个视频')
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
const playVideoWithNativeBridge = (filePath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.playVideo) {
|
||||
// iOS WebView 桥接
|
||||
window.webkit.messageHandlers.playVideo.postMessage({
|
||||
filePath: filePath
|
||||
});
|
||||
resolve();
|
||||
} else if (window.android && window.android.playVideo) {
|
||||
// Android WebView 桥接
|
||||
window.android.playVideo(filePath);
|
||||
resolve();
|
||||
} else if (window.plus) {
|
||||
// 使用 plus API 创建本地 HTTP 服务
|
||||
plus.bridge.exec('VideoPlayerModule', 'playVideoFromPath', [filePath],
|
||||
(httpUrl) => {
|
||||
console.log('获取到HTTP URL:', httpUrl);
|
||||
resolve(httpUrl);
|
||||
},
|
||||
(error) => {
|
||||
console.error('原生方法调用失败:', error);
|
||||
reject(error);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
reject(new Error('没有可用的原生桥接方法'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const getFilePath = async (file) => {
|
||||
try {
|
||||
// #ifdef H5
|
||||
// 将 plus 文件对象转换为 Blob
|
||||
return new Promise((resolve, reject) => {
|
||||
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, (fs) => {
|
||||
const reader = new plus.io.FileReader();
|
||||
|
||||
reader.onload = function (e) {
|
||||
// 将文件内容转换为 Blob
|
||||
const blob = new Blob([e.target.result], { type: file.type || 'video/mp4' });
|
||||
// 创建新的 File 对象
|
||||
const newFile = new File([blob], file.name || 'video.mp4', {
|
||||
type: file.type || 'video/mp4'
|
||||
});
|
||||
|
||||
// 创建新的 FormData
|
||||
// const formData = new FormData();
|
||||
// formData.append('file', newFile);
|
||||
// 添加其他需要的字段
|
||||
// formData.append('other_field', 'value');
|
||||
|
||||
resolve(newFile);
|
||||
};
|
||||
|
||||
reader.onerror = function (error) {
|
||||
console.error('读取文件失败:', error);
|
||||
reject(error);
|
||||
};
|
||||
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
return formData;
|
||||
// #endif
|
||||
} catch (error) {
|
||||
console.error('处理文件失败:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const onUploadImageVideo = async (file, type = 'image', resp) => {
|
||||
console.log(file, 'file')
|
||||
return new Promise(async (resolve) => {
|
||||
if (type === 'image') {
|
||||
@ -132,6 +308,7 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
form.append('file', file)
|
||||
form.append('source', 'fonchain-chat')
|
||||
form.append('urlParam', `width=${image.width}&height=${image.height}`)
|
||||
|
||||
let randomId = uniqueId()
|
||||
let newItem = {
|
||||
avatar: userStore.avatar,
|
||||
@ -164,6 +341,12 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
uploadImg(form, (e) => onProgressFn(e, randomId)).then(
|
||||
({ status, data, msg }) => {
|
||||
if (status == 0) {
|
||||
// 更新上传状态为成功
|
||||
const index = virtualList.value.findIndex(item => item.file_num === randomId)
|
||||
if (index !== -1) {
|
||||
virtualList.value[index].uploadStatus = 2
|
||||
virtualList.value[index].uploadCurrent = 100
|
||||
}
|
||||
resolve({
|
||||
type: 'image',
|
||||
url: data.ori_url,
|
||||
@ -173,6 +356,11 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
file_num: randomId,
|
||||
})
|
||||
} else {
|
||||
// 更新上传状态为失败
|
||||
const index = virtualList.value.findIndex(item => item.file_num === randomId)
|
||||
if (index !== -1) {
|
||||
virtualList.value[index].uploadStatus = 3
|
||||
}
|
||||
resolve('')
|
||||
message.error(msg)
|
||||
}
|
||||
@ -180,14 +368,15 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
)
|
||||
}
|
||||
} else {
|
||||
uni.getVideoInfo({
|
||||
src: fileUrl,
|
||||
success: (resp) => {
|
||||
console.log(resp)
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
form.append('source', 'fonchain-chat')
|
||||
form.append('type', 'video')
|
||||
form.append('urlParam', `width=${resp.width}&height=${resp.height}`)
|
||||
// 打印 FormData 内容
|
||||
for (let pair of form.entries()) {
|
||||
console.log('video form', `${pair[0]}: ${pair[1]}`);
|
||||
}
|
||||
let randomId = uniqueId()
|
||||
let newItem = {
|
||||
avatar: userStore.avatar,
|
||||
@ -196,7 +385,7 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
duration: parseInt(resp.duration),
|
||||
height: resp.height,
|
||||
name: '',
|
||||
url: fileUrl,
|
||||
url: resp.fileUrl,
|
||||
width: resp.width,
|
||||
},
|
||||
float: 'right',
|
||||
@ -216,9 +405,16 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
|
||||
}
|
||||
virtualList.value.unshift(newItem)
|
||||
console.log('uploadImg params', form)
|
||||
uploadImg(form, (e) => onProgressFn(e, randomId)).then(
|
||||
({ status, data, msg }) => {
|
||||
if (status == 0) {
|
||||
// 更新上传状态为成功
|
||||
const index = virtualList.value.findIndex(item => item.file_num === randomId)
|
||||
if (index !== -1) {
|
||||
virtualList.value[index].uploadStatus = 2
|
||||
virtualList.value[index].uploadCurrent = 100
|
||||
}
|
||||
console.log(data)
|
||||
resolve({
|
||||
type: 'video',
|
||||
@ -229,18 +425,43 @@ const onUploadImageVideo = async (file, type = 'image', fileUrl) => {
|
||||
file_num: randomId,
|
||||
})
|
||||
} else {
|
||||
// resolve('')
|
||||
// message.error(msg)
|
||||
// 更新上传状态为失败
|
||||
const index = virtualList.value.findIndex(item => item.file_num === randomId)
|
||||
if (index !== -1) {
|
||||
virtualList.value[index].uploadStatus = 3
|
||||
}
|
||||
resolve('')
|
||||
message.error(msg)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
})
|
||||
const form = new FormData()
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getVideoInfo = (filePath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
plus.io.getVideoInfo({
|
||||
filePath: filePath,
|
||||
success: (res) => {
|
||||
resolve({
|
||||
width: res.width,
|
||||
height: res.height,
|
||||
duration: res.duration,
|
||||
fileUrl: filePath,
|
||||
size: res.size
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('获取视频信息失败:', err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const base64ToFile = (base64) => {
|
||||
// base64转file
|
||||
const [header, base64String] = base64.split(';base64,')
|
||||
@ -351,7 +572,7 @@ const getCamera = () => {
|
||||
},
|
||||
)
|
||||
},
|
||||
() => {},
|
||||
() => { },
|
||||
{ index: '2' },
|
||||
)
|
||||
}
|
||||
@ -414,7 +635,23 @@ const chooseFile = () => {
|
||||
uploadStatus: 1, // 1 上传中 2 上传成功 3 上传失败
|
||||
}
|
||||
virtualList.value.unshift(newItem)
|
||||
uploadsStore.initUploadFile(res.tempFiles[0], props.talkParams, randomId)
|
||||
uploadsStore.initUploadFile(res.tempFiles[0], props.talkParams, randomId, (status, data, msg) => {
|
||||
if (status === 0) {
|
||||
// 更新上传状态为成功
|
||||
const index = virtualList.value.findIndex(item => item.file_num === randomId)
|
||||
if (index !== -1) {
|
||||
virtualList.value[index].uploadStatus = 2
|
||||
virtualList.value[index].uploadCurrent = 100
|
||||
}
|
||||
} else {
|
||||
// 更新上传状态为失败
|
||||
const index = virtualList.value.findIndex(item => item.file_num === randomId)
|
||||
if (index !== -1) {
|
||||
virtualList.value[index].uploadStatus = 3
|
||||
}
|
||||
message.error(msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user