利用uniapp中模仿抖音、滑动视频组件、首个视频自动播放、预加载、实现加载更多,超高性能

这篇具有很好参考价值的文章主要介绍了利用uniapp中模仿抖音、滑动视频组件、首个视频自动播放、预加载、实现加载更多,超高性能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

抖音效果图

小程序 视频预加载,uniapp,uni-app,前端,typescript,音视频

本内容主要实现了滑动视频组件、首个视频自动播放、预加载、实现加载更多,超高性能,

小程序 视频预加载,uniapp,uni-app,前端,typescript,音视频

前言:最近在做短剧,于是就在网上找了很多不错的例子,但是不是很完美,基本上都比较卡顿,我也是在站在巨人的肩膀上优化了一下。本片主要基于vue3、setup和ts开发的。

相关参考:

video | uni-app官网 (dcloud.net.cn)

uni.createVideoContext(videoId, this) | uni-app官网 (dcloud.net.cn)

项目结构:

小程序 视频预加载,uniapp,uni-app,前端,typescript,音视频

主要组件:代码里逻辑很清晰,就不再赘述了。video-play.vue

<template>
	<swiper class="video-swiper" circular @change="swiperChange" :current="state.current" :vertical="true"
		duration="800">
		<swiper-item v-for="(item, index) in state.displaySwiperList" :key="index">
			<view class="swiper-item" @click="handleClick">
				<video :id="`video${index}`" :controls="controls" :show-fullscreen-btn="false" :autoplay="false"
					:loop="loop" @ended="ended" @controlstoggle="controlstoggle" @play="onPlay" @error="emits('error')"
					class="video-player" :src="item.src" v-if="index === 0 || !state.isFirstLoad"></video>

				<slot :item="item"></slot>
			</view>
		</swiper-item>
	</swiper>
</template>

<script lang="ts" setup>
	import { getCurrentInstance, watch, onMounted, onUnmounted } from "vue";
	import { useState } from './moudle'

	interface IvideoItem {
		src : string;//视频链接
		title : string;
		id : string;
	}
	interface Iprops {
		videoList : Array<IvideoItem>
		loop ?: boolean //是否循环播放一个视频
		controls ?: boolean
		autoplay ?: boolean
		autoChange ?: boolean //是否自动滚动播放
		loadMoreOffsetCount ?: number //滚动加载阈值(即播放到剩余多少个之后触发加载更多


	}
	 
	const emits = defineEmits<{
		(e : 'play',value : Event) : void
		(e : 'error') : void
		(e : 'loadMore') : void
		(e : 'change',{
			index: number,
			detail: any,
		}) : void
		(e : 'controlstoggle',value : any) : void
		(e : 'click',value : Event) : void
		(e : 'ended') : void


	}>();
	const props = withDefaults(defineProps<Iprops>(), {
		videoList: () => [],
		loop: true,
		controls: true,
		autoplay: true,
		autoChange: true,
		loadMoreOffsetCount: 2
	})



	const state = useState()

	const initVideoContexts = () => {
		state.videoContexts = [
			uni.createVideoContext("video0", getCurrentInstance()),
			uni.createVideoContext("video1", getCurrentInstance()),
			uni.createVideoContext("video2", getCurrentInstance()),
		];
	};

	const onPlay = (e : Event) => {
		emits("play", e);
	};

	function handleClick(e : Event) {
		state.toggleShow = !state.toggleShow;
		emits("click", e);
	}
	function ended() {
		// 自动切换下一个视频
		if (props.autoChange) {
			if (state.displayIndex < 2) {
				state.current = state.displayIndex + 1;
			} else {
				state.current = 0;
			}
		}
		emits("ended");
	}
	/**
	 * 初始一个显示的swiper数据
	 * @originIndex  从源数据的哪个开始显示默认0,如从其他页面跳转进来,要显示第n个,这个参数就是他的下标
	 */
	function initSwiperData(originIndex = state.originIndex) {
		const originListLength = state.originList.length; // 源数据长度
		const displayList = [];
		displayList[state.displayIndex] = state.originList[originIndex];
		displayList[state.displayIndex - 1 == -1 ? 2 : state.displayIndex - 1] =
			state.originList[
			originIndex - 1 == -1 ? originListLength - 1 : originIndex - 1
			];
		displayList[state.displayIndex + 1 == 3 ? 0 : state.displayIndex + 1] =
			state.originList[originIndex + 1 == originListLength ? 0 : originIndex + 1];
		state.displaySwiperList = displayList;

		if (state.oid >= state.originList.length) {
			state.oid = 0;
		}
		if (state.oid < 0) {
			state.oid = state.originList.length - 1;
		}
		// 暂停所有视频
		state.videoContexts.map((item : any) => item?.stop());
		setTimeout(() => {
			// 当前视频
			if (props.autoplay) {
				state.videoContexts[state.displayIndex].play()

			}
		}, 600);
		// 数据改变
		emits("change", {
			index: originIndex,
			detail: state.originList[originIndex],
		});
		// 加载更多
		var pCount = state.originList.length - props.loadMoreOffsetCount;
		if (originIndex == pCount) {
			emits("loadMore");
		}
	}
	/**
	 * swiper滑动时候
	 */
	function swiperChange(event : any) {
		const { current } = event.detail;
		state.isFirstLoad = false;
		const originListLength = state.originList.length; // 源数据长度
		// 向后滚动
		if (state.displayIndex - current == 2 || state.displayIndex - current == -1) {
			state.originIndex =
				state.originIndex + 1 == originListLength ? 0 : state.originIndex + 1;
			state.displayIndex =
				state.displayIndex + 1 == 3 ? 0 : state.displayIndex + 1;
			state.oid = state.originIndex - 1;
			initSwiperData(state.originIndex);
		}
		// 如果两者的差为-2或者1则是向前滑动
		else if (
			state.displayIndex - current == -2 ||
			state.displayIndex - current == 1
		) {
			state.originIndex =
				state.originIndex - 1 == -1
					? originListLength - 1
					: state.originIndex - 1;
			state.displayIndex =
				state.displayIndex - 1 == -1 ? 2 : state.displayIndex - 1;
			state.oid = state.originIndex + 1;
			initSwiperData(state.originIndex);
		}
		state.toggleShow = true;
	}

	function controlstoggle(e : any) {
		state.showControls = e.detail.show;
		emits("controlstoggle", e);
	}

	watch(
		() => props.videoList,
		() => {
			if (props.videoList?.length) {
				state.originList = props.videoList;
				if (state.isFirstLoad || !state.videoContexts?.length) {
					initSwiperData();
					initVideoContexts();
				}
			}
		},
		{
			immediate: true,
		}
	);

	let loadTimer : any = null;
	onMounted(() => {
		// 为了首次只加载一条视频(提高首次加载性能),延迟加载后续视频
		loadTimer = setTimeout(() => {
			state.isFirstLoad = false;
			clearTimeout(loadTimer);
		}, 3000);
	})
	onUnmounted(() => {
		clearTimeout(loadTimer);
	})
</script>

<style lang="scss" scoped>
	.video-swiper {
		width: 100%;
		height: 100vh;
		background-color: #000;

		swiper-item {

			.video-player {
				width: 100%;
				height: 100vh;
			}
		}
	}
</style>

状态管理:

moudle.ts

import { reactive } from "vue"

const useState=()=>{
	return reactive({
		originList: [] as any, // 源数据
		displaySwiperList: [] as any, // swiper需要的数据
		displayIndex: 0, // 用于显示swiper的真正的下标数值只有:0,1,2。
		originIndex: 0, // 记录源数据的下标
		current: 0,
		oid: 0,
		showControls: "",
		toggleShow: true, // 显示面板
		videoContexts: [] as any,
		isFirstLoad: true,
	})
}
export {useState}

引用逻辑:

<template>
	<div class="video-container">
		<video-play :video-list="state.videoList" @loadMore="loadMore" >
			<!-- 此处data是从子组件获取的数据 不明白参考https://cn.vuejs.org/guide/components/slots.html#dynamic-slot-names-->
			<template v-slot="data">
				<view class="video-title"> {{ data.item.title }} </view>
			</template>
		</video-play>
	</div>
</template>
<script lang="ts" setup>
	import { reactive } from "vue";
	// 导入组件
	const state = reactive({
		videoList: [
			{
				src: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",
				id: "1",
				title: "亲近大自然"
			},
			{
				src: "https://img.chenggua.com/mnzcdcjgs.mp4",
				id: "2",
				title: "亲近大自然"
			},
			{
				src: "https://img.chenggua.com/mnzcdcjgs.mp4",
				id: "3",
				title: "亲近大自然"
			},
			{
				src: "http://vjs.zencdn.net/v/oceans.mp4",
				id: "4",
				title: "亲近大自然"
			},
			{
				src: "https://xjc.demo.hongcd.com/uploads/20210128/0c64cbeea28b10c06eee8728c762449e.mp4",
				id: "5",
				title: "亲近大自然"
			},
			{
				src: "https://xjc.demo.hongcd.com/uploads/20210327/1b72e1b6153cd29df07f5449991e8083.mp4",
				id: "6",
				title: "亲近大自然"
			},
			{
				src: "https://xjc.demo.hongcd.com/uploads/20230214/7e1a0baaebc4e656bbbfbc44d7a55a60.mp4",
				id: "7",
				title: "亲近大自然"
			},
		],
	});

	const loadMore = () => {
		state.videoList.push({
			src: "https://img.chenggua.com/mnzcdcjgs.mp4",
			id: state.videoList.length+"",
			title: '我是加载更多加载更多'+state.videoList.length
		})
	};

</script>
<style lang="scss">
	.video-title {
		position: absolute;
		left: 30rpx;
		top: 50rpx;
		color: #fff;
	}
</style>

以上测试逻辑都是基于小程序测试的,希望对于您有所帮助。文章来源地址https://www.toymoban.com/news/detail-758113.html

到了这里,关于利用uniapp中模仿抖音、滑动视频组件、首个视频自动播放、预加载、实现加载更多,超高性能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uniapp实现视频上下滑动功能(小程序)以及video组件的暂停和播放

    uni推荐使用swiper组件实现,在video组件的下面介绍有写。 这里实现方式是: 父组件先用swiper组件实现纵向滑动,然后在每个swiper-item中插入视屏组件video-item-vx(自己定义的组件),在video-item-vx组件中实现视屏播放,具体别的细节根据需要自己实现。 注意:不能无限添加swi

    2023年04月22日
    浏览(63)
  • uniapp中swiper的大坑,在swiper-item中嵌套video在移动端无法实现上下滑动的,要用nvue代替,从而实现抖音滑视频效果

    想做一个抖音滑屏切换视频的效果,结果。。。。。 研究了一天,发现在swiper-item中嵌套视频时,移动端只能滑动切换背景,视频在原位置是不会动的。。。。但是在h5端和小程序端可以完美运行,这就很让人生气了:  在移动端的时候,就会出现虽然切换到第二个视频了,

    2023年04月09日
    浏览(65)
  • uniapp实战仿写网易云音乐(三)—视频页面(scroll-view组件实现横线滑动,mescroll-uni实现视频列表,向下滑动刷新当前页面)

    接着上篇文章继续完成剩下的部分,本篇文章是完成第二个页面——视频页面的部分,视频还是没有做播放的效果,主要是做展示效果。下面附上两篇文章链接,没看过的同学可以回头看看: uniapp实战仿写网易云音乐(一)—底部工具栏以及首页轮播图swiper的实现 uniapp实战仿写

    2023年04月25日
    浏览(43)
  • vue3 - swiper插件 实现PC端的 视频滑动功能(仿抖音短视频)

     swiper官网 ​​​​​​swiper属性/组件查询 步骤: ① npm install swiper 安装 ② 基础模板:   如图: 属性: direction = \\\" \\\'vertical\\\' \\\" ,滑动方向,vertical 垂直方向。(注:一定要两对引号包裹着,否则不生效,还要给swiper设置实高) modules = \\\"modules\\\" grabCursor=\\\"true\\\" ,鼠标手掌形状

    2024年02月03日
    浏览(76)
  • uniapp - 仿抖音短视频项目

    特殊通知 1.请用户认真阅读以下说明,千万不能混淆页面随意引入,如果你发现运行后页面样式排版错乱,大概率是引入错误喔。 2.请App端用户将HbuilderX版本调整到3.3.9版本或3.3.9以下的版本,以规避list-cell渲染问题。 需求说明 在项目中内置短视频模块 功能说明 1.APP端 滑动

    2024年02月15日
    浏览(59)
  • uniapp组件库SwipeAction 滑动操作 使用方法

    目录 #平台差异说明 #基本使用 #修改按钮样式 #点击事件 #API #Props #Event 该组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。 注意 如果把该组件通过v-for用于左滑删除的列表,请保证循环的 :key 是一个唯一值,可以用数据的id或者title替代。 不能是数组循环

    2024年01月22日
    浏览(43)
  • 抖音自动生成视频、字幕、自动上传发布

    点击进入https://github.com/Richard0403/dy-auto https://github.com/Richard0403/dy-auto/assets/14147304/21400a42-9296-4956-9517-ced8d8bf4737 名称 功能 ffmpeg 处理视频的生成,语音添加,字幕的添加等 微软SpeechStudio 文字合成语音 whisper 语音生成字幕 jieba3k 用于文案的提取 playwright 用于自动化操作 环

    2024年02月08日
    浏览(54)
  • Python自动化实现抖音自动刷视频

    本文主要介绍了Python自动化实现抖音自动刷视频,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 环境准备 实现 Python3.5以上 Appium Server服务器 Android SDK,需要用到adb服务 需要依赖Appium-Pytho

    2024年02月12日
    浏览(35)
  • [MAUI]模仿iOS多任务切换卡片滑动的交互实现

    @ 目录 原理 创建布局 创建分布函数 创建动效 创建绑定数据 细节调整 首张卡片的处理 为卡片添加裁剪 跳转到最后一张卡片 项目地址 看了上一篇博文的评论,大家对MAUI还是比较感兴趣的,非常感谢大家的关注,这个专栏我争取周更😉。 App之间的多任务切换相信你们都很熟

    2024年02月02日
    浏览(87)
  • uniapp h5 竖向的swiper内嵌视频实现抖音短视频垂直切换,丝滑切换视频效果,无限数据加载不卡顿

    一、项目背景 :实现仿抖音短视频全屏视频播放、点赞、评论、上下切换视频、视频播放暂停、分页加载、上拉加载下一页、下拉加载上一页等功能。。。 二、前言 :博主一开始一直想实现类似抖音进入页面自动播放当前视频,上下滑动切换之后播放当前视频,但最后在

    2024年02月11日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包