关于TimePicker导致FC的问题解决方案

本文介绍了一个关于使用TimePicker控件导致程序崩溃的问题,并提供了解决方案:在TimePicker控件中加入<requestFocus/>标签。具体原因尚不明确,欢迎专业人士解答。
在写个小程序的时候发现使用了TimePicker这个控件之后程序会崩溃,经检查没有问题啊~~
经过一番折腾发现在TimePicker控件上加入一句   <requestFocus /> 标签就可以解决这个问题了。

代码如下:

    <TimePicker
                
                android:id="@+id/setAlarmTimePickerID"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_gravity="center_horizontal"
                android:layout_marginBottom="10dp"
                android:visibility="gone"
                >
                 <requestFocus />
            </TimePicker>

至于详细原因还不明白~还请大神们指出
import React, { useState } from 'react'; import { Select, DatePicker, TimePicker, Button, Table, Modal, Form, Input, ConfigProvider, Space, message, Spin, } from 'antd'; import { FormOutlined, PlusCircleOutlined, MinusCircleOutlined } from '@ant-design/icons'; import locale from 'antd/locale/zh_CN'; import dayjs, { Dayjs } from 'dayjs'; import 'dayjs/locale/zh-cn'; import { useSetPublish, useGetPublishHistory } from './request'; import type { PublishParams, PublishFormValues } from '@/types/autoPublish'; import {PROJECT_NAMES, statusMap, envMap, typeMap} from './config'; import { useQueryClient } from '@tanstack/react-query'; dayjs.locale('zh-cn'); const AutoPublish: React.FC = () => { const queryClient = useQueryClient(); const { data, isLoading } = useGetPublishHistory({ pageSize: '10', page: '1', }); const publishHistory = data?.data || []; const [messageApi, contextHolder] = message.useMessage(); const [chooseDate, setChooseDate] = useState<Dayjs | null>(dayjs()); const [chooseTime, setChooseTime] = useState<Dayjs | null>(dayjs()); const [isModalVisible, setIsModalVisible] = useState(false); const [form] = Form.useForm(); /** * 整合时间值 */ const handlePublishDate = (publishDate: Dayjs, publishTime: Dayjs) => { if (publishDate && publishTime) { const fullTime = publishDate .hour(publishTime.hour()) .minute(publishTime.minute()) .second(0); const formattedTime = fullTime.format('YYYY-MM-DD HH:mm:ss'); return formattedTime } } const { mutate } = useSetPublish(); /** * 新建发布 */ const newPublish = () => { setIsModalVisible(true); }; /** * 修改发布 */ const revisePublish = (record: PublishParams) => { const projects = record.product.map((item: any) => ({ productName: item.product_name, productTag: item.product_tag, })); // 解析发布时间 const publishTime = dayjs(record.publish_time); // 设置表单值 form.setFieldsValue({ projects: projects, branchVersion: record.branch_version, productEnv: record.publish_env.toString(), publishTime: record.publish_time, }); // 设置日期和时间选择器的值 setChooseDate(publishTime); setChooseTime(publishTime); setIsModalVisible(true); }; /** * 发布 */ const handleSubmit = (type: string) => { form.validateFields().then((values: PublishFormValues) => { if (!chooseDate || !chooseTime) { alert('请选择完整的日期和时间'); return; } const publishTime = handlePublishDate(chooseDate, chooseTime); const { projects, branchVersion, productEnv } = values; const publishType = type === 'schedule' ? 1 : 2; const publishStatus = 2; const params = { product: projects.map((p) => ({ product_name: p.productName, product_tag: p.productTag, })), branch_version: branchVersion, publish_time: publishTime!, publish_user: 'admin', publish_status: publishStatus, publish_type: publishType, publish_env: Number(productEnv), }; console.log(`【${type}】提交数据:`, params); mutate(params, { onSuccess: () => { messageApi.open({ type: 'success', content: '发布成功!', }); // 刷新列表 queryClient.invalidateQueries({ queryKey: ['publishHistory'], }); }, onError: (data) => { messageApi.open({ type: 'error', content: data.message || '发布失败~请重试!', }); } }); setIsModalVisible(false); }); }; /** * 禁用今天之前的日期 */ const disabledDate = (current: Dayjs) => { return current < dayjs().startOf('day'); }; /** * 禁用此刻之前时间点 */ const disabledDateTime = (current: Dayjs | null) => { const now = dayjs(); if(!current) return; if (current.isSame(now, 'day')) { return { disabledHours: () => range(0, now.hour()), disabledMinutes: (selectedHour: number) => selectedHour === now.hour() ? range(0, now.minute()) : [], }; } return {}; }; const range = (start: number, end: number) => { const result = []; for (let i = start; i < end; i++) { result.push(i); } return result; }; /** * 定义表格 */ const columns1 = [ { title: '发布时间', dataIndex: 'publish_time', key: 'publish_time', }, { title: '发布版本', dataIndex: 'branch_version', key: 'branch_version', }, { title: '发布状态', dataIndex: 'publish_status', key: 'publish_status', render: (status: number) => statusMap[status] || '未知类型', }, { title: '发布类型', dataIndex: 'publish_type', key: 'publish_type', render: (type: number) => typeMap[type] || '未知类型', }, { title: '发布环境', dataIndex: 'publish_env', key: 'publish_env', render: (text: number) => envMap[text] || '未知环境', }, { title: '编辑', key: 'edit', render: (_: any, record: PublishParams) => ( <FormOutlined onClick={() => revisePublish(record)} style={{ cursor: 'pointer' }} /> ), }, ]; const columns2 = [ { title: '项目名称', dataIndex: 'product_name', key: 'product_name', }, { title: 'Tag号', dataIndex: 'product_tag', key: 'product_tag', }, ]; if (isLoading) { return <Spin tip="Loading">{<a>加载中...</a>}</Spin>; } return ( <div style={{ padding: '20px' }}> {contextHolder} {/* 控件 */} <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '16px', marginBottom: '20px' }}> <Button type="primary" onClick={newPublish} style={{ backgroundColor: '#3662ec' }}> 新建发布 </Button> </div> {/* 表格 */} <Table columns={columns1} dataSource={publishHistory} rowKey={(record) => record.branch_version} expandable={{ expandedRowRender: (record) => ( <Table columns={columns2} dataSource={record.product || []} pagination={false} style={{ width: 500 }} rowKey={(item, index) => index!} /> ), }} /> {/* 编辑模态框 */} <Modal title="项目信息" open={isModalVisible} width={700} onCancel={() => setIsModalVisible(false)} footer={[ <Button key="back" onClick={() => setIsModalVisible(false)}> 取消 </Button>, <Button key="schedule" type="primary" onClick={() => handleSubmit('schedule')}> 预约发布 </Button>, <Button key="publish" type="primary" onClick={() => handleSubmit('rightNow')}> 立即发布 </Button>, ]} > <Form form={form} layout="horizontal" labelCol={{ span: 5 }} wrapperCol={{ span: 10 }} initialValues={{ projects: [ { productName: undefined, productTag: '', }, ], }} > <Form.List name="projects"> {(fields, { add, remove }) => ( <> {fields.map(({ key, name, ...restField }) => ( <Space key={key} style={{ display: 'flex', marginBottom: 0 }} align="baseline"> <Form.Item {...restField} name={[name, 'productName']} label="项目名称" labelCol={{ span: 9 }} wrapperCol={{ span: 16 }} rules={[{ required: true, message: '请选择项目名称' }]} > <Select showSearch optionFilterProp="children" options={PROJECT_NAMES.map((name) => ({ label: name, value: name, }))} style={{ width: 250 }} /> </Form.Item> <Form.Item {...restField} name={[name, 'productTag']} label="Tag" labelCol={{ span: 10 }} wrapperCol={{ span: 50 }} rules={[{ required: true, message: '请输入 Tag' }]} > <Input /> </Form.Item> <MinusCircleOutlined onClick={() => remove(name)} /> </Space> ))} <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}> <Button type="dashed" onClick={() => add()} icon={<PlusCircleOutlined />} style={{ width: 200, height: 35, borderRadius: 6, display: 'flex', alignItems: 'center', justifyContent: 'center' }} > 添加项目 </Button> </div> </> )} </Form.List> <Form.Item label="选择版本" name="branchVersion" rules={[{ required: true }]}> <Input /> </Form.Item> <Form.Item label="选择环境" name="productEnv" rules={[{ required: true }]}> <Select style={{ width: 150 }}> <Select.Option value="1">测试环境</Select.Option> <Select.Option value="2">生产环境</Select.Option> </Select> </Form.Item> <Form.Item label={ <span> <span style={{ fontSize: '18px', color: 'rgb(255, 141, 142)'}}>*</span> 选择时间 </span> } > <Space> <ConfigProvider locale={locale}> <DatePicker format="YYYY-MM-DD" value={chooseDate} disabledDate={disabledDate} onChange={(date) => setChooseDate(date ? dayjs(date) : null)} /> </ConfigProvider> <TimePicker format="HH:mm" value={chooseTime} disabledTime={() => disabledDateTime(chooseDate)} onChange={(time) => setChooseTime(time ? dayjs(time) : null)} /> </Space> </Form.Item> </Form> </Modal> </div> ); }; export default AutoPublish; 其中,TimePicker的disabledTime ts类型报错如下: Type '() => { disabledHours: () => number[]; disabledMinutes: (selectedHour: number) => number[]; } | { disabledHours?: undefined; disabledMinutes?: undefined; } | undefined' is not assignable to type '(date: Dayjs) => DisabledTimes'. Type '{ disabledHours: () => number[]; disabledMinutes: (selectedHour: number) => number[]; } | { disabledHours?: undefined; disabledMinutes?: undefined; } | undefined' is not assignable to type 'DisabledTimes'. Type 'undefined' is not assignable to type 'DisabledTimes'.ts(2322) interface.d.ts(139, 5): The expected type comes from property 'disabledTime' which is declared here on type 'IntrinsicAttributes & Omit<TimePickerProps, "ref"> & RefAttributes<PickerRef>' (property) disabledTime?: ((date: dayjs.Dayjs) => DisabledTimes) | undefined
09-03
import React, { useState } from ‘react’; import { Select, DatePicker, TimePicker, Button, Table, Modal, Form, Input, ConfigProvider, Space, message, Spin, } from ‘antd’; import { FormOutlined, PlusCircleOutlined, MinusCircleOutlined } from ‘@ant-design/icons’; import locale from ‘antd/locale/zh_CN’; import dayjs, { Dayjs } from ‘dayjs’; import ‘dayjs/locale/zh-cn’; import { useSetPublish, useGetPublishHistory } from ‘./request’; import type { PublishParams, PublishFormValues } from ‘@/types/autoPublish’; import { PROJECT_NAMES, statusMap, envMap, typeMap, statusOption, envOption } from ‘./config’; import { scriptsManagementService } from “@/api”; import { useQueryClient } from ‘@tanstack/react-query’; dayjs.locale(‘zh-cn’); const AutoPublish: React.FC = () => { const queryClient = useQueryClient(); const [pageSize] = useState(10); const [currentPage, setCurrentPage] = useState(1); const [selectEnv, setSelectEnv] = useState(1); const [messageApi, contextHolder] = message.useMessage(); const [chooseDate, setChooseDate] = useState<Dayjs | null>(dayjs()); const [chooseTime, setChooseTime] = useState<Dayjs | null>(dayjs()); const [branchVersionFilter, setBranchVersionFilter] = useState<string | null>(null); const [isModalVisible, setIsModalVisible] = useState(false); const [form] = Form.useForm(); /** * 获取历史数据 */ const { data, isLoading } = useGetPublishHistory({ pageSize: pageSize.toString(), page: currentPage.toString(), }); const { data: versionData, isLoading: loading } = useGetPublishHistory({ pageSize: pageSize.toString(), page: ‘1’, branch_version: branchVersionFilter || ‘’, //publish_env: 1, //isFinal:1 }); const publishHistory = data?.data || []; const dataByVersion = versionData?.data || []; const total = data?.total || 0; /** * 整合时间值 */ const handlePublishDate = (publishDate: Dayjs, publishTime: Dayjs) => { if (publishDate && publishTime) { const fullTime = publishDate .hour(publishTime.hour()) .minute(publishTime.minute()) .second(0); const formattedTime = fullTime.format('YYYY-MM-DD HH:mm:ss'); return formattedTime } } const { mutate } = useSetPublish(); /** * 新建发布 */ const newPublish = (publishEnv: number) => { setSelectEnv(publishEnv); setIsModalVisible(true); }; /** * 修改发布 */ const revisePublish = (record: PublishParams) => { const projects = record.product.map((item: any) => ({ productName: item.product_name, productTag: item.product_tag, })); // 解析发布时间 const publishTime = dayjs(record.publish_time); // 设置表单值 form.setFieldsValue({ projects: projects, branchVersion: record.branch_version, productEnv: record.publish_env.toString(), publishTime: record.publish_time, }); // 设置日期和时间选择器的值 setChooseDate(publishTime); setChooseTime(publishTime); setIsModalVisible(true); }; /** * 发布 */ const handleSubmit = (type: string) => { form.validateFields().then((values: PublishFormValues) => { if (!chooseDate || !chooseTime) { alert('请选择完整的日期和时间'); return; } const publishTime = handlePublishDate(chooseDate, chooseTime); const { projects, branchVersion, productEnv } = values; const publishType = type === 'schedule' ? 1 : 2; const publishStatus = 2; // 校验项目名称 let set = new Set(); for (let i = 0; i < projects.length; i++) { const productName = projects[i].productName; if (set.has(productName)) { messageApi.open({ type: 'warning', content: '项目名称重复了!', }); return } else { set.add(productName) } } const params = { product: projects.map((p) => ({ product_name: p.productName, product_tag: p.productTag, })), branch_version: branchVersion, publish_time: publishTime!, publish_user: 'admin', publish_status: publishStatus, publish_type: publishType, publish_env: Number(productEnv), }; console.log(`【${type}】提交数据:`, params); mutate(params, { onSuccess: () => { messageApi.open({ type: 'success', content: '发布成功!', }); // 刷新列表 queryClient.invalidateQueries({ queryKey: ['publishHistory'], }); }, onError: (data) => { messageApi.open({ type: 'error', content: data.message || '发布失败~请重试!', }); } }); setIsModalVisible(false); }); }; /** * 请求版本数据 */ const fetchVersionData = async (branchVersion: string) => { const params = { branch_version: branchVersion, page: '1', pageSize: '10' }; try { const data = await scriptsManagementService.getPublishHistory({ params }); console.log('获取到数据:', data); // 可选:手动更新缓存 queryClient.setQueryData(['publishHistory', 'v1', '1', '10'], data); } catch (error) { console.error('请求失败:', error); } }; /** * 按版本查询 */ // const getHistoryByVersion = (branchVersion: string) => { // setBranchVersionFilter(branchVersion); // } /** * 禁用今天之前的日期 */ const disabledDate = (current: Dayjs) => { return current < dayjs().startOf('day'); }; /** * 禁用此刻之前时间点 */ const disabledDateTime = (current: Dayjs | null) => { const now = dayjs(); if (!current) return {}; if (current.isSame(now, 'day')) { return { disabledHours: () => range(0, now.hour()), disabledMinutes: (selectedHour: number) => selectedHour === now.hour() ? range(0, now.minute()) : [], }; } return {}; }; const range = (start: number, end: number) => { const result = []; for (let i = start; i < end; i++) { result.push(i); } return result; }; /** * 分页控制器 */ const handlePageChange = (page: number) => { setCurrentPage(page); }; /** * 定义表格 */ const columns1 = [ { title: '发布时间', dataIndex: 'publish_time', key: 'publish_time', }, { title: '发布版本', dataIndex: 'branch_version', key: 'branch_version', }, { title: '发布状态', dataIndex: 'publish_status', key: 'publish_status', render: (status: number) => statusMap[status] || '未知类型', }, { title: '发布类型', dataIndex: 'publish_type', key: 'publish_type', render: (type: number) => typeMap[type] || '未知类型', }, { title: '发布环境', dataIndex: 'publish_env', key: 'publish_env', render: (text: number) => envMap[text] || '未知环境', }, { title: '编辑', key: 'edit', render: (_: any, record: PublishParams) => ( <FormOutlined onClick={() => revisePublish(record)} style={{ cursor: 'pointer' }} /> ), }, ]; const columns2 = [ { title: '项目名称', dataIndex: 'product_name', key: 'product_name', }, { title: 'Tag号', dataIndex: 'product_tag', key: 'product_tag', }, ]; if (isLoading || loading) { return <div style={{ textAlign: 'center', lineHeight: '500px' }}> <Spin tip="Loading">{<a>加载中...</a>}</Spin> </div> } return ( <div style={{ padding: '20px' }}> {contextHolder} {/* 控件 */} <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '16px', marginBottom: '20px' }}> <div style={{ alignItems: 'center' }}> <span style={{ fontSize: '16px', marginLeft: '20px' }}>版本查询:</span> <Select options={publishHistory.map((item) => ({ label: item.branch_version, value: item.branch_version, }))} onChange={(value) => setBranchVersionFilter(value)} style={{ width: 120, marginLeft: '10px' }} allowClear /> </div> <div style={{ alignItems: 'center' }}> <span style={{ fontSize: '16px', marginLeft: '20px' }}>发布状态:</span> <Select options={statusOption} style={{ width: 120, marginLeft: '10px' }} allowClear /> </div> <div style={{ alignItems: 'center' }}> <span style={{ fontSize: '16px', marginLeft: '20px', fontWeight: 'bold' }}>新建发布:</span> <Select options={envOption} onChange={newPublish} style={{ width: 120, marginLeft: '10px' }} /> </div> {/* <Button type="primary" onClick={newPublish} style={{ backgroundColor: '#3662ec', marginLeft: '20px'}}> 新建发布 </Button> */} </div> {/* 表格 */} <Table columns={columns1} dataSource={branchVersionFilter ? dataByVersion : publishHistory} rowKey={(record) => record.branch_version} pagination={{ current: currentPage, pageSize: pageSize, total: total, onChange: handlePageChange, showSizeChanger: false, }} expandable={{ expandedRowRender: (record) => ( <Table columns={columns2} dataSource={record.product || []} pagination={false} style={{ width: 500 }} rowKey={(item, index) => index!} /> ), }} /> {/* 编辑模态框 */} <Modal title="项目信息" open={isModalVisible} width={700} onCancel={() => setIsModalVisible(false)} footer={[ <Button key="back" onClick={() => setIsModalVisible(false)}> 取消 </Button>, <Button key="schedule" type="primary" onClick={() => handleSubmit('schedule')}> 预约发布 </Button>, <Button key="publish" type="primary" onClick={() => handleSubmit('rightNow')}> 立即发布 </Button>, ]} > <Form form={form} layout="horizontal" labelCol={{ span: 5 }} wrapperCol={{ span: 10 }} initialValues={{ projects: [ { productName: undefined, productTag: '', }, ], }} > <Form.List name="projects"> {(fields, { add, remove }) => ( <> {fields.map(({ key, name, ...restField }) => ( <Space key={key} style={{ display: 'flex', marginBottom: 0 }} align="baseline"> <Form.Item {...restField} name={[name, 'productName']} label="项目名称" labelCol={{ span: 9 }} wrapperCol={{ span: 16 }} rules={[{ required: true, message: '请选择项目名称' }]} > <Select showSearch optionFilterProp="children" options={PROJECT_NAMES.map((name) => ({ label: name, value: name, }))} style={{ width: 250 }} /> </Form.Item> <Form.Item {...restField} name={[name, 'productTag']} label="Tag" labelCol={{ span: 10 }} wrapperCol={{ span: 50 }} rules={[{ required: true, message: '请输入 Tag' }]} > <Input /> </Form.Item> <MinusCircleOutlined onClick={() => remove(name)} /> </Space> ))} <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}> <Button type="dashed" onClick={() => add()} icon={<PlusCircleOutlined />} style={{ width: 200, height: 35, borderRadius: 6, display: 'flex', alignItems: 'center', justifyContent: 'center' }} > 添加项目 </Button> </div> </> )} </Form.List> <Form.Item label="选择版本" name="branchVersion" rules={[{ required: true }]}> <Input /> </Form.Item> <Form.Item label="选择环境" name="productEnv" rules={[{ required: true }]} initialValue={selectEnv}> <Select options={envOption} style={{ width: 150 }} disabled /> </Form.Item> <Form.Item label={ <span> <span style={{ fontSize: '18px', color: 'rgb(255, 141, 142)' }}>*</span> 选择时间 </span> } > <Space> <ConfigProvider locale={locale}> <DatePicker format="YYYY-MM-DD" value={chooseDate} disabledDate={disabledDate} onChange={(date) => setChooseDate(date ? dayjs(date) : null)} /> </ConfigProvider> <TimePicker format="HH:mm" value={chooseTime} disabledTime={() => disabledDateTime(chooseDate)} onChange={(time) => setChooseTime(time ? dayjs(time) : null)} /> </Space> </Form.Item> </Form> </Modal> </div> ); }; export default AutoPublish; 为什么下面这个下拉框值一改变,会全体更新,下拉框的值也回到了最初的状态? 方案一是使用useMemo(),方案二是避免不必要的重新请求
09-11
<template> <div id="video_window" class="video_window"> <div class="header-wrapper"> <h3>{{props.deviceId}}——{{props.selectedCamera.name}}——Camera</h3> <el-button class="close-btn" circle @click="handleCloseAspect" ><el-icon><Close /></el-icon></el-button> </div> <el-form :model="formData" class="timepicker"> <el-form-item label="起始时间"> <el-date-picker v-model="formData.starttime" type="datetime" placeholder="请选择起始时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYYMMDDTHHmmss[Z]"></el-date-picker> </el-form-item> <el-form-item label="结束时间"> <el-date-picker v-model="formData.endtime" type="datetime" placeholder="请选择结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYYMMDDTHHmmss[Z]"></el-date-picker> </el-form-item> <el-form-item><el-button type="primary" :disabled="isCreated" @click="startPlay">播放</el-button></el-form-item> <el-form-item><el-button type="primary" :disabled="isDisabled" @click="stopPlay">停止</el-button></el-form-item> <el-form-item><el-button type="primary" :disabled="isDisabled" @click="pausePlay">{{ isPlaying ? "暂停":"继续" }}</el-button></el-form-item> </el-form> <div class="mainAspect"> <div v-if="videoLoading" class="custom-loading-layer"> <div class="loading-spinner"></div> <p>视频加载中...</p> </div> <video id="videoElement" class="videoElement" ref="flvPlayer" autoplay preload="metadata"></video> </div> </div> </template> <script setup> import flvjs from "flv.js" import { Close } from '@element-plus/icons-vue' import { computed, onMounted, ref, watch, onUnmounted,defineEmits,nextTick } from 'vue'; import { getActionCallBack,videoCloseCallBack } from '../api'; import {useStatusStore} from '../stores/videoCache' import { ElMessage } from "element-plus"; import dayjs from 'dayjs'; const props = defineProps({ deviceId: { type: String, required: true }, selectedCamera:{ type: Object, required: true } }); const emit= defineEmits(['close']) const videoCache=useStatusStore(); const originVideoPath='rtsp://admin:sess2025@' const flvPath=ref(null); const flvPlayer = ref(null); let player=null; const videoLoading=ref(false); const formData=ref({starttime:null,endtime:null}); const isDisabled=ref(true); const isPlaying=ref(true); const isCreated=ref(false); // watch( // ()=>props.selectedCamera, // async (newVal,oldVal) =>{ // console.log(newVal); // console.log(oldVal); // if (player) { // player.destroy(); // player=null; // videoLoading.value=false; // await closeOldVideoStream(oldVal.ip, oldVal.channelNo); // } // },{deep:true} // ) const handleCloseAspect=()=>{ emit('close'); } const fetchVideoStream=async (starttime,endtime)=>{ const res = await getActionCallBack(originVideoPath+String(props.selectedCamera.ip)+":554/streaming/tracks/"+String(props.selectedCamera.channelNo)+"01?starttime="+starttime+"^&endtime="+endtime); flvPath.value=res.data; console.log(flvPath.value); }; const closeVideoStream=async ()=>{ const queryTime=flvPath.value.split('callback')[1]; const res = await videoCloseCallBack(props.selectedCamera.ip,props.selectedCamera.channelNo,queryTime); console.log(res.data); }; // const closeOldVideoStream=async (ip, channelNo)=>{ // const res = await videoCloseCallBack(ip, channelNo); // console.log(res.data); // }; const initPlayer=()=>{ if(flvPath.value!==null){ if (flvjs.isSupported()) { let videoElement = document.getElementById('videoElement') player = flvjs.createPlayer({ type: 'flv', isLive: true, fluid: true, stashInitialSize: 128,// 减少首桢显示等待时长 url: flvPath.value, //url地址 }) player.attachMediaElement(videoElement) player.load() player.on(flvjs.Events.METADATA_ARRIVED,()=>{ videoLoading.value=false; }) player.play() } }else{ return; } }; const startPlay=async ()=>{ const now=dayjs().format('YYYYMMDDTHHmmss[Z]'); if(formData.value.starttime===null){ ElMessage.error("请选择起始时间!"); return null; }else if(formData.value.endtime===null){ ElMessage.error("请选择结束时间!!"); return null; }else if(formData.value.endtime>=now){ ElMessage.error("结束时间不能大于当前时间!") return null; }else if(formData.value.endtime<=formData.value.starttime){ ElMessage.error("结束时间不能小于开始时间!") return null; }else{ videoLoading.value=true; await fetchVideoStream(formData.value.starttime,formData.value.endtime); initPlayer(); isDisabled.value=false; isCreated.value=true; } } const stopPlay=()=>{ if(player){ closeVideoStream(); player.destroy(); player=null; isCreated.value=false; isDisabled.value=true; isPlaying.value=true; } } const pausePlay=()=>{ if(player){ if(!isPlaying.value){ console.log(isPlaying.value); player.play(); isPlaying.value=true; }else{ player.pause(); // 暂停播放 isPlaying.value=false; } } } onUnmounted(() => { if (player) { closeVideoStream(); player.destroy(); player=null; } }); </script> <style scoped> .video_window{ position: fixed; top: 15%; left: 30%; width: 49%; height: 70%; border-radius: 5%; background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(12px); border-radius: 20px; box-shadow: 0 12px 40px rgba(100, 100, 150, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.6) inset; overflow: hidden; transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.1); } /* 标题栏 - 渐变背景与现代化按钮 */ .header-wrapper { padding: 18px 25px; background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); position: relative; box-shadow: 0 4px 12px rgba(0,0,0,0.08); } .header-wrapper h3 { margin: 0; color: white; font-weight: 500; font-size: 1.2rem; letter-spacing: 0.5px; text-shadow: 0 1px 2px rgba(0,0,0,0.1); } /* 时间选择表单 - 融入整体设计 */ .timepicker { padding: 15px 30px; background: rgba(245, 245, 255, 0.85); border-bottom: 1px solid rgba(210, 210, 255, 0.6); display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; } .el-form-item { margin-bottom: 0; } .el-form-item label { color: #5a5a8a; font-weight: 500; } .el-date-editor, .el-button { border-radius: 12px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); } .el-button--primary { background: linear-gradient(135deg, #7f5af0 0%, #2cb67d 100%); border: none; transition: all 0.3s ease; } .el-button--primary:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(127, 90, 240, 0.3); } .mainAspect{ width: 100%; height: 82%; background: linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%); position: relative; overflow: hidden; border-radius: 0 0 28px 28px; } .videoElement{ width: 100%; height: 100%; transform-origin: center; object-fit: contain; transition: opacity 0.3s; } .close-btn { position: absolute; right: 10px; top: 10px; z-index: 20; background: rgba(255,255,255,0.2); border: none; transition: all 0.3s ease; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } /*加载状态样式 */ .custom-loading-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 10; background: rgba(15, 12, 41, 0.85); backdrop-filter: blur(4px); color: #94a3b8; } .loading-spinner { width: 40px; height: 40px; border: 3px solid rgba(255,255,255,0.3); border-radius: 50%; border-top-color: gray; animation: spin 1s linear infinite; border-top-color: #2cb67d; border-left-color: rgba(124, 58, 237, 0.5); border-bottom-color: rgba(44, 182, 125, 0.3); border-right-color: rgba(124, 58, 237, 0.2); border-width: 4px; } @keyframes spin { to { transform: rotate(360deg); } } </style>我这个为什么推流成功但是flvjs播放不出来
10-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值