vue3实现上传视频后,根据视频自动生成封面图

1、数据表格

<template>
    <el-card class="box-card">
        <template #header>
            <div class="card-header" ref="searchBox">
                <el-form :inline="true" :model="form" class="demo-form-inline" ref="ruleFormRef" size="small">
                    <el-form-item label="视频名称" prop="VideoName">
                        <el-input v-model="form.VideoName" placeholder="请输入要查询的视频名称" />
                    </el-form-item>
                    <!-- <el-form-item label="视频分类编码" prop="videoTypeCode">
                        <el-tree-select :props="{ value: 'bianMa', label: 'mingCheng', children: 'children' }"
                            v-model="form.VideoTypeCode" :data="videoTypeCodetreedata" check-strictly filterable />
                    </el-form-item> -->
                    <el-form-item>
                        <el-button size="small" type="primary" @click="onSubmit(ruleFormRef)">
                            <el-icon>
                                <search />
                            </el-icon>查询
                        </el-button>
                        <el-button size="small" @click="resetForm(ruleFormRef)">
                            <el-icon>
                                <refresh-right />
                            </el-icon>重置
                        </el-button>
                        <el-button size="small" type="primary" @click="add">新增</el-button>
                        <!-- <el-popconfirm title="确认要进行批量删除吗?" @confirm="Del" confirm-button-text="是" cancel-button-text="否">
                            <template #reference>
                                <el-button type="danger">删除</el-button>
                            </template>
                        </el-popconfirm> -->
                    </el-form-item>
                </el-form>
                <!-- <p>
                    <el-button type="primary" @click="add">新增</el-button>
                    <el-popconfirm title="确认要进行批量删除吗?" @confirm="Del" confirm-button-text="是" cancel-button-text="否">
                        <template #reference>
                            <el-button type="danger">删除</el-button>
                        </template>
                    </el-popconfirm>
                </p> -->
            </div>
        </template>
        <el-row>
            <el-col :span="3">
                <el-tree :props="defaultProps" :load="loadNode" :expand-on-click-node="false"
                    @node-click="handleNodeClick" lazy />
            </el-col>
            <el-col :span="21">
                      <el-table :data="tableData" size="small"  :style="{height:contentHeight}" style="width: 100%;" ref="multipleTableRef">
                    <!-- <el-table-column type="selection" width="55" /> -->
                    <el-table-column label="序号" type="index" :index="indexMethod" width="70">
			</el-table-column>

                    <el-table-column label="文件名称" v-if="permission.tableList.findIndex((v) => (v === '文件名称')) < 0">
                        <template #default="scope">
                            <div>{{ scope.row.videoName }}</div>
                        </template>
                    </el-table-column>
                    <el-table-column label="点击次数" v-if="permission.tableList.findIndex((v) => (v === '点击次数')) < 0" width="100">
                        <template #default="scope">
                            <div>{{ scope.row.playbackCount }}</div>
                        </template>
                    </el-table-column>
                    <el-table-column label="分类" v-if="permission.tableList.findIndex((v) => (v === '分类')) < 0" width="180">
                        <template #default="scope">
                            <div>{{ scope.row.videoType }}</div>
                        </template>
                    </el-table-column>
                    <el-table-column label="视频封面" v-if="permission.tableList.findIndex((v) => (v === '视频封面')) < 0" width="120">
                        <template #default="scope">
                            <div class="demo-image__preview" v-if="scope.row.videoCover">
                                <el-image
                                style="width: 100px; height: 50px"
                                :src="DownloadImgServerUrl + scope.row.videoCover"
                                :zoom-rate="1.2"
                                :max-scale="7"
                                :min-scale="0.2"
                                :preview-src-list="[DownloadImgServerUrl + scope.row.videoCover]"
                                show-progress
                                :initial-index="4"
                                fit="cover"
                                preview-teleported="true"
                                />
                            </div>
                        </template>
                    </el-table-column>
                    <el-table-column label="查看视频" v-if="permission.tableList.findIndex((v) => (v === '查看视频')) < 0" width="120">
                        <template #default="scope">
                            <div style="color:blue;cursor:pointer;" @click="toShipin(scope.row)">点击查看</div>
                        </template>
                    </el-table-column>
                    <el-table-column label="创建时间" width="170" v-if="permission.tableList.findIndex((v) => (v === '创建时间')) < 0">
                        <template #default="scope">
                            <div>{{ scope.row.createTime }}</div>
                        </template>
                    </el-table-column>

                    <el-table-column label="创建人" v-if="permission.tableList.findIndex((v) => (v === '创建人')) < 0" width="100">
                        <template #default="scope">
                            <div>{{ scope.row.createUser }}</div>
                        </template>
                    </el-table-column>
                    <el-table-column label="修改时间" width="170" v-if="permission.tableList.findIndex((v) => (v === '修改时间')) < 0">
                        <template #default="scope">
                            <div>{{ scope.row.updateTime }}</div>
                        </template>
                    </el-table-column>

                    <el-table-column label="修改人" v-if="permission.tableList.findIndex((v) => (v === '修改人')) < 0" width="100">
                        <template #default="scope">
                            <div>{{ scope.row.updateUser }}</div>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" fixed="right" align="right" width="200">
                        <template #default="scope">
                            <el-button size="small" type="primary" @click="handleEdit(scope.$index, scope.row)" v-if="permission.listButton.findIndex((v) => (v === '编辑')) < 0">编辑
                            </el-button>
                            <el-popconfirm title="确定要删除吗?" @confirm="handleDelete(scope.$index, scope.row)"
                                confirm-button-text="是" cancel-button-text="否" v-if="permission.listButton.findIndex((v) => (v === '删除')) < 0">
                                <template #reference>
                                    <el-button size="small" type="danger">删除
                                    </el-button>
                                </template>
                            </el-popconfirm>
                        </template>
                    </el-table-column>
                </el-table>
                
<el-pagination  :total="form.Total" small
            @current-change="handleCurrentChange"             
            v-model:current-page="form.pageIndex"
      v-model:page-size="form.pageSize"
      :page-sizes="[10, 20, 50, 100]"
      background
      right
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="handleSizeChange"
      />
            </el-col>
        </el-row>
    </el-card>
    <addVue :addVisible="addVisible" :info="info" @CloseAdd="CloseAdd"></addVue>
    <el-drawer v-model="drawer" title="查看视频" @closed="closevideo">
        <!-- <vue3VideoPlay v-bind="options" poster="../../../assets/logo.png" /> -->
        <video controls ref="videoRef" style="position:relative;width:100%;height: 100%;"
                                :src="DownloadImgServerUrl + options.src">
                                <!-- <source :src="form.videoUrl" type="video/mp4">
                                            <source :src="form.videoUrl" type="video/ogg">
                                            <source :src="form.videoUrl" type="video/webm">
                                            很抱歉,您的浏览器暂时不支持播放组件,请尝试替换浏览器! -->
                            </video>
    </el-drawer>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, toRaw } from 'vue'
import type { ElTable } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { Search, Phone, RefreshRight } from '@element-plus/icons-vue'
import addVue from './components/add.vue'
import { VideoCenterModel } from '../VideoCenter/class/VideoCenterModel'
import { delRole, batchDelRole } from '../../../http/index'
import { GetData, TongYongGet } from '../../../http/tongyong'
import { getListByCode } from '../../../http/zidian'
import { ElTree } from 'element-plus'
import type Node from 'element-plus/es/components/tree/src/model/node'
import Tool from '../../../global'
const DownloadImgServerUrl = new Tool().DownloadImgServerUrl.toString();
interface Tree {
    id: number
    mingCheng: string
    children?: Tree[]
}
const defaultProps = {
    children: 'children',
    label: 'name',
    id: 'id',
}
//树状图节点点击事件
function handleNodeClick(data: any) {
    // console.log(data)
    form.VideoTypeCode = data.typeCode;
    LoadTableData()
}
const handleSizeChange = (val: number) => {
    form.pageSize=val
    LoadTableData()
}
let dicp_parent = {
    Name: "",
    PageIndex: 1,
    PageSize: 999
}

const loadNode = (node: Node, resolve: (data: Tree[]) => void) => {
    if (node.level === 0) {
        dicp_parent.Name=""
        loadTree(resolve, dicp_parent)
    } else if (node.level >= 1) {
        dicp_parent.Name="das789ah32490ads@#$"
        loadTree(resolve, dicp_parent)
    }
}
const loadTree = async (resolve: any, get_fileTypeCode: any) => {
    let data = (await GetData(get_fileTypeCode, "/VideoType/GetList") as any).data;
    if (data.length > 0) {
        resolve(data);
    } else {
        resolve([]);
    }
}

const closevideo = () => {

    options.src = ''
}

//视频播放开始
let drawer = ref(false)
//视频组件
const options = reactive({
    width: '100%', //播放器高度
    height: '100%', //播放器高度
    color: '#409eff', //主题色
    title: '', //视频名称
    src: '', //视频源
    muted: true, //静音
    webFullScreen: false,
    speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速
    autoPlay: true, //自动播放
    loop: false, //循环播放
    mirror: false, //镜像画面
    ligthOff: false, //关灯模式
    volume: 0.3, //默认音量大小
    control: true, //是否显示控制器
});

const showsp = ref({ id: 0 })

const toShipin = (row: any) => {

    showsp.value.id = row.id
    options.src = row.videoUrl

    var parms = {
        VideoCenterId: row.id,
        LogType: 0,
        Title: row.videoName
    }

    if (row.videoUrl != '') {
        const res = GetData(parms, "/VideoViewRecord/Add") as any as boolean
    }
    drawer.value = true
}
//视频播放结束
const ruleFormRef = ref<FormInstance>()
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
const form = reactive({
    VideoTypeCode: "",
    VideoName: "",
    pageIndex: 1,
    pageSize: 50,
    Total: 0
})

const searchBox=ref()
const contentHeight=ref()
onMounted(async () => {
    
    setTimeout( () =>{
        const a = document.body.clientHeight
        // const a = document.documentElement.clientHeight
        const b=searchBox.value.offsetHeight + 36;
        //屏幕高度 - 查询- 第一个横向 - 选项卡 -分页
        const c=a - b - 120 -70; 
        contentHeight.value=c.toString()+'px'
    },500)
    LoadTableData()
    // Init()
})
//权限屏蔽内容列表
const permission = ref({
    queryItem: [''],//查询项 id=2
    topButton: [''],//全局按钮 id=3
    tableList: [''],//表格列 id=4
    listButton: [''],//操作项 id=5
    formItem: [''],//表单项 id=6
    formButton: ['']//表单按钮 id=7
})

const indexMethod = (index: number) => {
  return (form.pageIndex-1)*form.pageSize+index+1
}
//根据需求,获取权限列表
const LoadPermissions = async () => {
    let parms = {
        Url: window.location.hash.replace('#', ''),
        Ids: [2, 3, 4, 5]
    }
    let res = await GetData(parms, "/MenuFunctionInfo/GetFuncsByUrl") as any
    permission.value = res
    // showPage.value = true
}
const videoTypeCodetreedata = ref()
let dicp_videoTypeCode = {
    MingCheng: "",
    BianMa: "",
    QiTaCanShu: "",
    FuJiId: 0,
    Description: "",
    PageIndex: 1,
    FuJiCode: 'SHIPINFENLEI',
    PageSize: 999
}

// const Init = async () => {
//     videoTypeCodetreedata.value = [{ bianMa: '', mingCheng: '全部视频分类编码' }]
//     videoTypeCodetreedata.value = videoTypeCodetreedata.value.concat((await getListByCode(dicp_videoTypeCode)).data)
// }

//表格
const tableData = ref<Array<VideoCenterModel>>()

const LoadTableData = async (name: string = "") => {
    let parms = {
        VideoTypeCode: form.VideoTypeCode,
        VideoName: form.VideoName,
        PageIndex: form.pageIndex,
        PageSize: form.pageSize
    }
    let res = await GetData(parms, "/VideoCenter/GetList") as any
    form.Total = res.total
    tableData.value = res.data as VideoCenterModel[]

}
//分页
const handleCurrentChange = (val: number) => {
    form.pageIndex = val
    LoadTableData()
}

const onSubmit = async (ruleFormRef: FormInstance | undefined) => {
    if (!ruleFormRef) return;
    await ruleFormRef.validate((valid, fields) => {
        if (valid) {
            form.VideoTypeCode = "";
            LoadTableData()
        } else {
            console.log('error submit!', fields)
        }
    })
}
const resetForm = (ruleFormRef: FormInstance | undefined) => {
    if (!ruleFormRef) return
    ruleFormRef.resetFields()
    LoadTableData()
}

const handleQuery = (index: number, row: VideoCenterModel) => {
    
    queryDialog.value = true
}
const addVisible = ref(false)
const add = () => {
    addVisible.value = true
}
const CloseAdd = () => {
    addVisible.value = false
    info.value = undefined
    LoadTableData()
}

const info = ref()
const handleEdit = (index: number, row: VideoCenterModel) => {
    info.value = JSON.stringify(row)
    addVisible.value = true
}
//单个删除
const handleDelete = async (index: number, row: VideoCenterModel) => {
    tableData.value = tableData.value?.filter(s => s.id != row.id)
    const res = await TongYongGet("/VideoCenter/Del?id=" + row.id) as any as boolean
    if (res) {
        ElMessage({
            message: '删除成功!',
            type: 'success',
        })
    }
}
//批量删除
const Del = async () => {
    let arr: any[] = multipleTableRef.value?.getSelectionRows()
    let ids: string = arr.map(item => { return "'" + item.id + "'" }).join(',')
    const res = await TongYongGet("/VideoCenter/BatchDel?ids=" + ids) as any as boolean
    if (res) {
        ElMessage({
            message: '删除成功!',
            type: 'success',
        })
        LoadTableData()
    }
}
const queryDialog = ref(false)
const queryDialogClose = () => {
    queryDialog.value = false;
}

</script>
<style  lang="scss" scoped>
.el-pagination {
    margin-top: 50px;
}

.cell {
    text-align: center !important;
}

.queryTable {
    width: 500px;
    border-collapse: collapse;

    tr {
        height: 50px;

        td {
            padding: 10px;
        }

        .left {
            width: 30%;
            background-color: #F5F7FA;
        }

        .right {
            width: 80%;
        }
    }
}

.imageVideo {
    width: 100%;
    max-height: 200px;
    height: 200px;
}
</style>

2、新增页面

<template>
    <el-dialog v-model="addVisible" :title="info == undefined ? '新增' : '修改'" width="70%" :before-close="handleClose">
        <el-form :model="form" label-width="170px" class="form" :rules="rules" ref="ruleFormRef" size="small">
            <el-row>
                <el-col :span="20">
                    <el-form-item label="视频名称" prop="videoName">
                        <el-input v-model="form.videoName" />
                    </el-form-item>
                </el-col>
                <el-col :span="20">
                    <el-form-item label="视频分类" prop="videoTypeCode">
                        <el-tree-select :props="{ value: 'typeCode', label: 'name', children: 'children' }"
                            v-model="form.videoTypeCode" :data="videoTypeCodetreedata" check-strictly filterable />
                    </el-form-item>
                </el-col>
                <!-- <el-col :span="20">
                    <el-form-item label="封面图" prop="videoCover">
                        <el-upload class="avatar-uploader" :action="UploadImgServerUrl" :show-file-list="false" accept=".png,.jpg,.jpeg,.gif,.bmp,.svg"
                            :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
                            <img v-if="form.videoCover" :src="DownloadImgServerUrl + form.videoCover" class="avatar" style="max-width:200px" />
                            <el-icon v-else class="avatar-uploader-icon">
                                <Plus />
                            </el-icon>
                        </el-upload>
                    </el-form-item>
                </el-col> -->
                <el-col :span="20">
                    <el-form-item label="视频文件" prop="videoUrl">
                        <el-upload v-model:file-list="fileList" class="upload-demo" :action="UploadImgServerUrl" accept=".mp4,.avi,.mov,.wmv"
                            :on-change="handleChange" :on-remove="removeFile" multiple="false" limit="1">
                            <el-button type="primary">请选择要上传的视频文件</el-button>
                        </el-upload>
                    </el-form-item>
                </el-col>
                
                <el-col :span="20">
                    <el-form-item label="上传视频生成封面图" prop="videoCover">
                        <div>
                            <div v-show="false">
                                <video ref="video" :src="DownloadImgServerUrl + form.videoUrl" @loadeddata="captureFrame" crossorigin="anonymous" style="width: 100%;height: 200px;"></video>
                            </div>
                            <canvas ref="canvas" style="display:none;" v-show="false"></canvas>
                            <img :src="thumbnail" v-if="thumbnail">
                        </div>
                    </el-form-item>
                </el-col>
                <el-col :span="20">
                    <el-form-item label="排序" prop="sort">
                        <el-input v-model="form.sort" type="number" />
                    </el-form-item>
                </el-col>
            </el-row>
            <!-- 按钮操作组 -->
            <el-form-item class="btn">
                <el-button size="small" type="primary" @click="submit(ruleFormRef)">确定</el-button>
                <el-button size="small" @click="close(ruleFormRef)">取消</el-button>
            </el-form-item>
        </el-form>
    </el-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, defineProps, computed, defineEmits, onMounted, watch, toRaw } from 'vue'
import { addMenu, editMenu, getMenuDataNew } from '../../../../http';
import { VideoCenterModel } from '../../VideoCenter/class/VideoCenterModel'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { getListByCode } from '../../../../http/zidian'
import { base64ToFile, GetData } from '../../../../http/tongyong'
import { number } from 'echarts';
import type { UploadProps, UploadUserFile } from 'element-plus'
import Tool from '../../../../global'
import { Plus } from '@element-plus/icons-vue'

import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import axios from 'axios';

// const uploadFileAction = new Tool().UploadFileServerUrl
const UploadImgServerUrl = new Tool().UploadImgServerUrl
const DownloadImgServerUrl = new Tool().DownloadImgServerUrl
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
    console.log("上传文件:" + rawFile);
    // if (rawFile.type !== 'image/jpeg') {
    //     ElMessage.error('请上传jpg头像!')
    //     return false
    // } else 
    if (rawFile.size / 1024 / 1024 > 200) {
        ElMessage.error('文件大小不要超200MB哦!')
        return false
    }
    return true
}

const handleAvatarSuccess: UploadProps['onSuccess'] = (
    response,
    uploadFile
) => {
        form.value.videoCover = response.result;
}

const fileList = ref<UploadUserFile[]>([
    //   {
    //     name: 'food.jpeg',
    //     url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
    //   },
    //   {
    //     name: 'food2.jpeg',
    //     url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
    //   },
])

const getSort = async () => {
    var parms = {
    }

    const res = await GetData(parms, "/VideoCenter/getSort") as any as number
        if (res) {
            form.value.sort=res
        }

}

const removeFile=()=>{
    form.value.videoUrl = ''
        form.value.oldVideoFileName = ''
        fileList.value = []
  
}

const handleChange: UploadProps['onChange'] = (uploadFile: any, uploadFiles) => {
    // fileList.value = []
    if (uploadFile.response && uploadFile.response.isSuccess) {
        form.value.videoCover = "";
        // let data = uploadFile.response.result.data
        // console.log("后缀名:" + data.fileExt);
        // console.log("文件大小" + data.filesize);
        // console.log("文件MD5值" + data.mD5);
        // console.log("新文件名字" + data.newname);
        // console.log("旧文件名字" + data.oldname);
        // console.log("硬盘地址" + data.relativePath);
        // console.log("网络地址" + data.url);
        form.value.videoUrl = uploadFile.response.result;
        form.value.oldVideoFileName = uploadFile.name
        captureFrame()
    }
}

const ruleFormRef = ref<FormInstance>()
const props = defineProps({
    addVisible: Boolean,
    info: VideoCenterModel
})
const form = ref({
    id: props.info?.id,
    sort: 0,
    videoTypeCode: '',
    oldVideoFileName: '',
    videoName: '',
    videoUrl: '',
    videoCover: ''
})
const rules = reactive<FormRules>({
    videoName: [{ required: true, message: '请输入视频名称', trigger: 'blur' }],
    videoTypeCode: [{ required: true, message: '请选择视频分类', trigger: 'blur' }],
    videoUrl: [{ required: true, message: '请上传视频', trigger: 'blur' }],
    sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
})

//监听
watch(
    () => props.info,
    (newInfo, oldInfo) => {
        if (newInfo != undefined) {
            let currInfo: VideoCenterModel = (JSON.parse(newInfo as any)) as VideoCenterModel
            form.value = {
                id: currInfo.id,
                sort: currInfo.sort,
                videoTypeCode: currInfo.videoTypeCode,
                videoName: currInfo.videoName,
                videoUrl: currInfo.videoUrl,
                oldVideoFileName: currInfo.oldVideoFileName,
                videoCover: currInfo.oldVideoFileName
            }
            if (currInfo.videoUrl != '') {
                fileList.value = [{
                    name: currInfo.oldVideoFileName,
                    url: currInfo.videoUrl,
                }]
            }


        } else {
            form.value = {
                id: 0,
                sort: 0,
                videoTypeCode: '',
                oldVideoFileName: '',
                videoName: '',
                videoUrl: '',
                videoCover: ''
            }

            fileList.value = []
            getSort()
        }
    }
);
//defineEmits用于定义回调事件,里面是数组,可以定义多个事件
const emits = defineEmits(["CloseAdd"])
const handleClose = (done: () => void) => {
    emits("CloseAdd")
}


const videoTypeCodetreedata = ref()
let dicp_videoTypeCode = {
    MingCheng: "",
    BianMa: "",
    QiTaCanShu: "",
    FuJiId: 0,
    Description: "",
    PageIndex: 1,
    FuJiCode: 'SHIPINFENLEI',
    PageSize: 999
}


const xingbietreedata = ref()
const shifoutreedata = ref()

onMounted(() => {
    getSort()
    LoadSelectData()
})


let dicp_parent = {
    Name: "",
    PageIndex: 1,
    PageSize: 999
}

const LoadSelectData = async () => {

    videoTypeCodetreedata.value = [{ typeCode: '', name: '请选择分类' }]
    const gsres = await GetData(dicp_parent, "/VideoType/GetList") as any
    videoTypeCodetreedata.value = videoTypeCodetreedata.value.concat(gsres.data)

    xingbietreedata.value = [{ bianMa: 0, mingCheng: '女' }, { bianMa: 1, mingCheng: '男' }]
    shifoutreedata.value = [{ bianMa: 0, mingCheng: '否' }, { bianMa: 1, mingCheng: '是' }]

}

const submit = async (ruleFormRef: FormInstance | undefined) => {
    if (!ruleFormRef) return
    if (form.value.videoUrl == '') {
        ElMessage({
            message: '请上传视频文件',
            type: 'error',
        })
        return
    }

    ruleFormRef.validate((valid) => {
        if (valid) {
            addOrEdit(ruleFormRef)
            // 
        } else {
            ElMessage({
                message: '请填写完整信息!',
                type: 'warning',
            })
        }
    });
}

const addOrEdit = async (ruleFormRef: FormInstance | undefined) => {
    if (!ruleFormRef) return

    var parms = {
        Id: form.value.id,
        Sort: form.value.sort,
        VideoTypeCode: form.value.videoTypeCode,
        VideoName: form.value.videoName,
        VideoUrl: form.value.videoUrl,
        OldVideoFileName: form.value.oldVideoFileName,
        VideoCover: form.value.videoCover
    }

    if (props.info == undefined) {
        // 执行添加逻辑 
        const res = await GetData(parms, "/VideoCenter/Add") as any as boolean
        if (res) {
            ElMessage({
                message: '添加成功!',
                type: 'success',
            })
            //添加菜单之后重新加载下拉框
            LoadSelectData()
            ruleFormRef.resetFields()
            getSort()
            emits("CloseAdd")
        }
    } else {
        // 执行修改逻辑
        const res = await GetData(parms, "/VideoCenter/Edit") as any as boolean
        if (res) {
            ElMessage({
                message: '编辑成功!',
                type: 'success',
            })
            //添加菜单之后重新加载下拉框
            LoadSelectData()
            ruleFormRef.resetFields()
            emits("CloseAdd")
        }
    }

}
const close = (ruleFormRef: FormInstance | undefined) => {
    if (!ruleFormRef) return
    ruleFormRef.resetFields()
    emits("CloseAdd")
}

//生成封面图
const video = ref<HTMLVideoElement | null>(null);
const canvas = ref<HTMLCanvasElement | null>(null);
const thumbnail = ref<string>('');
const captureFrame =async () => {
    if(form.value.videoUrl && !form.value.videoCover){
        const videoref = video.value;
        const canvasref =canvas.value;
        const context = canvasref!.getContext('2d');
        canvasref!.width = videoref!.videoWidth;
        canvasref!.height = videoref!.videoHeight;
        context!.drawImage(videoref!, 0, 0, canvasref!.width, canvasref!.height);
        thumbnail.value = canvasref!.toDataURL('image/png');
    // console.log(thumbnail.value,"生成封面图");
        //将base64转换为文件
        
        var  NewImg = base64ToFile(thumbnail.value);
        try{
        const formData = new FormData();
        formData.append('file', NewImg);
        const response = await axios.post(UploadImgServerUrl.toString(), formData,{headers:{'Content-Type': 'multipart/form-data'}});
            if(response.data.isSuccess){
                // ElMessage({
                //     message: '上传成功!',
                //     type: 'success',
                // })
                var newtu = response.data.result;
                form.value.videoCover = newtu;
            }else{
                ElMessage({
                    message: '上传失败,请联系系统管理员!',
                    type: 'error',
                })
            }
        }catch(err){
            ElMessage({
                message: '上传失败,请联系系统管理员!',
                type: 'error',
            })
        }
    }
}
</script>
<style lang="scss" scoped>
.form {
    min-height: 500px;

    .btn {
        position: absolute;
        bottom: 10px;
    }
}
</style>

3、base64图片信息转为文件类型

//将base64转换为文件
export const base64ToFile=(data:any)=> {
    // 将base64 的图片转换成file对象上传 atob将ascii码解析成binary数据
    let binary = atob(data.split(',')[1]);
    let mime = data.split(',')[0].match(/:(.*?);/)[1];
    let array: number[] = [];
    for (let i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    let fileData = new Blob([new Uint8Array(array)], {
        type: mime,
    });
    let file = new File([fileData], `${new Date().getTime()}.png`, {
        type: mime
    });
    return file;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值