html5 video audio currentTime 设定失效、重头开始播放

正确答案 (2020.6.23更新)

在服务器里,根据请求,确定客户端请求的视频范围是多少,然后返回对应的请求内容,就可以实现点击调整视频音频播放进度里

ctx.set({
	// 'status': '206 Partial Content',
	'Content-Range': `bytes ${start}-${end}/${size}`,
	'Content-Length': (end - start) + 1
})

ctx.body = fs.readFileSync(mp3).slice(start, end+1)

完整代码如下

router.get('/uploadFile/:filename', async(ctx, next) => {
	var mp3 = path.resolve('/server/uploadFile/' + ctx.params.filename)

	if (fs.existsSync(mp3)) {

		let size = fs.statSync(mp3).size

		ctx.set({
			'Content-Type': 'audio/mpeg;charset=UTF-8',
			'Accept-Ranges': 'bytes',
		})
	
		if (ctx.headers.range === 'bytes=0-1') {
			ctx.set('Content-Range', `bytes 0-1/${size}`)
			ctx.body = '1'
		} else if (ctx.headers.range) {

			// 可能遇到的5种情况:
			// 1.表示第二个500字节:bytes=500-999
			// 2.表示最后500个字节:bytes=-500
			// 3.表示500字节以后的范围:bytes=500-
			// 4.第一个和最后一个字节:bytes=0-0,-1
			// 5.同时指定几个范围:bytes=500-600,601-999

			let _range = ctx.request.header.range
			// _range = 'bytes=5000000-' //
			let [start, end] =  _range.replace('bytes=', '').split('-')
			start = parseInt(start, 10)
			  end = parseInt(end, 10)

			if ( !isNaN(start) && isNaN(end) ) {
				start = start
				end = size - 1
			}
			if ( isNaN(start) && !isNaN(end) ) {
				start = size - end
				end = size - 1
			}
			// console.log(start, end)

			// Handle unavailable range request
			if ( start >= size || end >= size ) {
				ctx.set({
					'status': '416 Range Not Satisfiable',
					'Content-Range': `bytes */${size}`
				})
			}

			ctx.response.status = 206
			ctx.set({
				// 'status': '206 Partial Content',
				'Content-Range': `bytes ${start}-${end}/${size}`,
				'Content-Length': (end - start) + 1
			})

			ctx.body = fs.readFileSync(mp3).slice(start, end+1)
			
		} else {
			ctx.set({
				'Accept-Ranges': 'bytes',
				// 'Access-Control-Allow-Credentials': true,
				// 'Access-Control-Allow-Headers': 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range',
				// 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
			})
			console.log('文件存在')
			const src = fs.createReadStream(mp3)
			ctx.body = src
		}

	} else {
		ctx.body = 'error: 你所访问的文件并不存在, 路径:' + mp3
	}
})

-------------------------------- 以下是以前写的,解决问题的过程 --------------------------------
------------------------------------------- 分割线 2020.6.23 -------------------------------------------


记一巨坑

今天我在vue中写一个音频播放器的时候,想做点击前进/后退 15s 的功能,
后面发现不管我怎么查,怎么找,都只搜索到 audio.currentTime += 15 这种方法。

但是我就纳闷了,为啥我的就是不行?
而搜索的所有文章,不管中文 英文,都是说 audio.currentTime += 15 这种方法 就可以了。

直到后面,我看到了这篇文章 html5 video currentTime 设定失效、重头开始播放

才知道,原来 能不能 前进/后退 15s 的功能,还需要音频源文件 支持才行的。


有的 音视频源文件,可以说是根本没有 关键帧,

比如 我所使用的音频源文件:http://localhost:3308/01.m4a
所以只要你执行 audio.currentTime += 15 就会自动跳回到开始,重头开始播放


经过对与视频多媒体对学习和查看资料得出结论:

关键帧:

视频中对关键帧是有限的,理论上我们快进的话只可以跳转到关键帧,因为非关键帧是无法播放的。

播放器对于视频快进的处理方式:

高性能解决方式:

当我们在电脑端浏览器对视频快进的时候,如果目标时间点不是关键帧,浏览器会对该部分视频重新解码,将这一秒变成关键帧,再次编码。所以电脑端或者部分性能强悍的播放器是可以随便跳转的。

低性能解决方式:

播放器会自动跳转到该时间点最近到关键帧。但是如果该时间点与关键帧的播放时间过长,将会重头播放视频。(目前发现手机端的微信H5播放器就是这样的)

对该情况的解决办法:

1、放弃低性能播放器的H5播放点跳转。
2、对源视频重新转码,并提高关键帧分布率。(原本质量就很差的视频,转码效果不大)
3、使用HlS格式的流媒体格式视频,并且控制TS切片数量。

你可能感兴趣的:(JavaScript,node.js)