2023,祝我的学习突飞猛进。

195 阅读1分钟

hi,好久不见,我是ly,好久不见,最近发生了许多新鲜的事物,我来了Blog。 2023,我将和大家分享,有趣的、轻松的、我认为的复杂的代码和事物。

分享一首音乐music.163.com/#/song?id=2…

在我的工作里,常用的是一下这些,最近有在研究cocos!

Num.one(小程序-支付宝小程序-微信小程序-钉钉小程序)

Num.two(后台管理)

pie title In my work: Technology Stack
"pig" : 30
"uniapp" : 85
"vue" : 100

分享一个视频(完整播放器)

组件展示+页面传值+组件代码的编译

nnnn.png

<view>
    <video-player autoplay :originalUrl="srcUrl" :title="title" 
    :poster="imgUrl" ></video-player>
</view>
<template>
	<view:style="{width,height}"class="video-container">
		<view v-if="!showVideo" class="loading-box">
			<image class="loading-img abs-center"	src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-098edbd3-5122-424e-90ff-8c8635c9fd75/8ca2275a-f53f-40ef-b1f3-1051706135af.gif"></image>
		</view>
		<video
			v-if="showVideo"
			id="video-player"
			class="video-box"
			:src="playUrl"
			:poster="posterUrl"
			:autoplay="autoplay"
			:loop="loop"
			:muted="muted"
			:page-gesture="pageGesture"
			:enable-progress-gesture="enableProgressesture"
			:show-mute-btn="showMuteBtn"
			:enable-play-gesture="enablePlayGesture"
			:vslide-gesture="vslideGesture"
			:vslide-gesture-in-fullscreen="vslideGestureInFullscreen"
			:show-center-play-btn="false"
			:title="title"
			@loadedmetadata="loadedmetadata"
			@play="onPlay"
			@pause="onPause"
			@ended="onEnded"
			@timeupdate="timeupdate"
			@fullscreenchange="fullscreenchange"
			@controlstoggle="controlstoggle"
		>
			<cover-view v-if="loading" class="loading-box text-white">
				<cover-image
					class="loading-img abs-center"
					src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-098edbd3-5122-424e-90ff-8c8635c9fd75/8ca2275a-f53f-40ef-b1f3-1051706135af.gif"
				></cover-image>
			</cover-view>

			<cover-view v-if="showPlay && !autoplay" class="play-box abs-center" @click="onCenterPlayBtnClick">
				<cover-image
					class="play-img"
					src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-098edbd3-5122-424e-90ff-8c8635c9fd75/a8a12b71-eca3-423a-81fa-3adac1d5ac1f.png"
				></cover-image>
			</cover-view>

			<cover-image
				v-if="showMenuBtn"
				class="more"
				src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-098edbd3-5122-424e-90ff-8c8635c9fd75/1490996b-eeee-4545-95b7-d61e66234b80.png"
				@click="moreBtnClick"
			></cover-image>

			<cover-view v-if="showMenu" class="menu-box" style="color: #fff;">
				<cover-view class="video-speed-box">
					<cover-view>播放速度</cover-view>
					<cover-view class="speed-wrapper">
						<cover-view
							class="speed-item"
							v-for="item in speedList"
							:key="item"
							:class="[item === currentSpeed ? 'speed-item-active' : 'speed-item-diactive']"
							@click="onChangeSpeed(item)"
						>
							{{ item }}倍
						</cover-view>
					</cover-view>
				</cover-view>
				<cover-view class="video-quality-box">
					<cover-view>清晰度</cover-view>
					<cover-view class="quality-wrapper">
						<cover-view
							class="speed-item"
							v-for="item in qualityList"
							:key="item.value"
							:class="[item.value === currentQuality ? 'speed-item-active' : 'speed-item-diactive']"
							@click="onChangeQuality(item.value)"
						>
							{{ item.text }}
						</cover-view>
					</cover-view>
				</cover-view>
			</cover-view>
		</video>

		<uni-popup ref="popup" type="bottom" background-color="#fff">
			<view class="popup-box">
				<view style="margin-top: 12rpx;">
					<view>播放速度</view>
					<view class="speed-box">
						<view
							class="speed-item"
							v-for="item in speedList"
							:key="item"
							:class="[item === currentSpeed ? 'speed-item-active' : 'speed-item-diactive']"
							@click="onChangeSpeed(item)"
						>
							{{ item }}倍
						</view>
					</view>
				</view>

				<view style="margin-top: 40rpx;">
					<view>清晰度</view>
					<view class="speed-box">
						<view
							class="speed-item"
							v-for="item in qualityList"
							:key="item.value"
							:class="[item.value === currentQuality ? 'speed-item-active' : 'speed-item-diactive']"
							@click="onChangeQuality(item.value)"
						>
							{{ item.text }}
						</view>
					</view>
				</view>
			</view>
		</uni-popup>
	</view>
</template>
<script>
import throttle from 'lodash/throttle'

const throttled = throttle(
	function(e) {
		const { currentTime } = e.detail
		this.playProgress = currentTime
		this.$emit('timeupdate', e)
	},
	2000,
	{
		leading: false
	}
)
export default {
	props: {
		width: {
			type: String,
			default: '100%'
		},
		height: {
			type: String,
			default: '450rpx'
		},
		// 标清播放地址
		standardUrl: {
			type: String,
			required: true
		},
		// 高清播放地址
		highUrl: {
			type: String,
			default: ''
		},
		// 超高清播放地址
		ultraUrl: {
			type: String,
			default: ''
		},
		// 原画播放地址
		originalUrl: {
			type: String,
			default: ''
		},
		posterUrl: {
			type: String,
			default: ''
		},
		autoplay: {
			type: Boolean,
			default: false
		},
		loop: {
			type: Boolean,
			default: false
		},
		muted: {
			type: Boolean,
			default: false
		},
		initialTime: {
			type: Number,
			default: 0
		},
		direction: {
			type: Number,
			default: 90
		},
		objectFit: {
			type: String,
			default: 'contain'
		},

		title: {
			type: String,
			default: '视频播放'
		},
		pageGesture: {
			type: Boolean,
			default: true
		},
		enableProgressesture: {
			type: Boolean,
			default: true
		},
		showMuteBtn: {
			type: Boolean,
			default: false
		},
		enablePlayGesture: {
			type: Boolean,
			default: false
		},
		vslideGesture: {
			type: Boolean,
			default: false
		},
		vslideGestureInFullscreen: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			// 0 标清
			// 1 高清
			// 2 超高清
			// 3 原画
			loading: true,
			showPlay: false,
			videoContext: null,
			currentSpeed: 1,
			speedList: [0.5, 0.8, 1, 1.25, 1.5, 2],
			showVideo: false,
			playProgress: 0,
			hasChangeQuality: false,
			hasFullScreen: false,
			showMenu: false,
			showMenuBtn: false,
			currentQuality: -1
		}
	},
	computed: {
		urlChange() {
			const { standardUrl, highUrl, ultraUrl, originalUrl } = this
			return { standardUrl, highUrl, ultraUrl, originalUrl }
		},
		playUrl() {
			let url = ''
			const { standardUrl, highUrl, ultraUrl, originalUrl, currentQuality } = this
			switch (currentQuality) {
				case 0:
					url = standardUrl
					break
				case 1:
					url = highUrl
					break
				case 2:
					url = ultraUrl
					break
				case 3:
					url = originalUrl
					break
			}

			return url
		},
		qualityList() {
			const list = []
			this.standardUrl &&
				list.push({
					text: '标清',
					value: 0
				})
			this.highUrl &&
				list.push({
					text: '高清',
					value: 1
				})
			this.ultraUrl &&
				list.push({
					text: '超清',
					value: 2
				})
			this.originalUrl &&
				list.push({
					text: '原画',
					value: 3
				})
			return list
		}
	},
	watch: {
		urlChange(val) {
			this.initQuality()
		},
		initialTime(value) {
			if (!this.videoContext) {
				this.videoContext = uni.createVideoContext('video-player', this)
			}
			setTimeout(() => {
				this.playProgress = value
				this.videoContext.seek(value)
			}, 300)
		}
	},
	created() {
		if (this.initialTime) {
			this.playProgress = this.initialTime
		}

		this.initQuality()
	},
	mounted() {
		this.videoContext = uni.createVideoContext('video-player', this)
	},
	methods: {
		initQuality() {
			let quality = -1
			const { standardUrl, highUrl, ultraUrl, originalUrl } = this
			if (standardUrl) {
				quality = 0
			} else if (highUrl) {
				quality = 1
			} else if (ultraUrl) {
				quality = 2
			} else if (originalUrl) {
				quality = 3
			}

			if (quality !== -1) {
				this.currentQuality = quality
				this.playProgress = 0
				this.initVideo()
				this.emitQualityChange()
			}
		},
		timeupdate: throttled,
		initVideo() {
			this.showVideo = false
			setTimeout(() => {
				this.showVideo = true
				this.loading = true
				this.videoContext = uni.createVideoContext('video-player', this)
			}, 300)
		},
		onChangeQuality(value) {
			if (value !== this.currentQuality) {
				throttled.cancel
				this.hasChangeQuality = true
				this.currentQuality = value
				this.initVideo()
				this.emitQualityChange()
			}
			this.$refs.popup.close()
			this.showMenu = false
		},
		onChangeSpeed(value) {
			this.currentSpeed = value
			this.videoContext.playbackRate(value)
			this.$refs.popup.close()
			this.showMenu = false
		},
		moreBtnClick() {
			if (this.hasFullScreen) {
				this.showMenu = true
			} else {
				this.$refs.popup.open()
			}
		},
		controlstoggle(e) {
			const show = e.detail.show
			if (show) {
				this.showMenuBtn = true
			} else {
				this.showMenuBtn = false
				this.showMenu = false
			}
		},
		fullscreenchange(e) {
			this.hasFullScreen = e.detail.fullscreen
		},
		onPlay() {
			this.showPlay = false
			this.playing = true
		},
		onPause() {
			if (this.hasChangeQuality) return
			this.playing = false
		},

		onEnded() {
			this.$emit('ended')
			if (this.autoplay) return
			this.playing = false
			this.playProgress = 0
			throttled.cancel
			this.showPlay = true
		},
		onCenterPlayBtnClick() {
			this.showPlay = false
			this.videoContext.play()
		},
		loadedmetadata() {
			this.loading = false
			this.showPlay = true
			this.videoContext.seek(this.playProgress)
			this.playing && this.videoContext.play()
			this.hasChangeQuality = false
		},
		onTimeupdate(e) {
			this.loading && (this.loading = false)
		},

		emitQualityChange() {
			this.$emit('qualitychange', this.currentQuality)
		}
	}
}
</script>
<style lang="scss" scoped>
.speed-box {
	margin-top: 28rpx;
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: 16rpx;
	font-size: 24rpx;
	.speed-item {
		text-align: center;
		padding: 12rpx 0;
		border-radius: 8rpx;
	}

	.speed-item-diactive {
		border: 1rpx solid #eee;
	}
	.speed-item-active {
		background-color: #2979ff;
		color: #fff;
	}
}
.popup-box {
	padding: 28rpx;
}
.abs-center {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
}
.video-container {
	position: relative;
	background-color: #000;
	box-sizing: border-box;
	.loading-box {
		position: absolute;
		left: 0;
		top: 0;
		right: 0;
		bottom: 0;
		z-index: 3;
		background-color: #000;
		.loading-img {
			width: 80rpx;
			height: 80rpx;
		}
	}
}
.video-box {
	width: 100%;
	height: 100%;

	.menu-box {
		position: absolute;
		right: 0;
		top: 0;
		width: 60%;
		height: 100%;
		background-color: #000;
		padding: 28rpx var(--status-bar-height);
		z-index: 4;
		box-sizing: border-box;
		font-size: 24rpx;
		display: flex;
		flex-direction: column;
		justify-content: center;
		.video-quality-box {
			margin-top: 28rpx;
		}

		.speed-wrapper,
		.quality-wrapper {
			display: flex;
			flex-wrap: wrap;
			margin-top: 28rpx;
		}
		.speed-item {
			width: 110rpx;
			padding: 20rpx 0;
			text-align: center;
		}

		.speed-item-active {
			color: #2979ff;
		}
	}

	.more {
		position: absolute;
		width: 50rpx;
		height: 50rpx;
		right: var(--status-bar-height);
		top: var(--status-bar-height);
	}

	.play-box {
		width: 90rpx;
		height: 90rpx;
		background-color: rgba(#fff, 0.8);
		border-radius: 2000px;
		display: flex;
		align-items: center;
		justify-content: center;
		.play-img {
			width: 70rpx;
			height: 70rpx;
		}
	}
}
</style>

你有更好的方法,可以留言。大家一起畅所欲言,在知识的海洋里,博览代码桥段,希望我们的2023年都能实现我们自己想要的目标,祝大家每天快乐。