七牛云-开源的播放器 sdk
一。项目中安装
https://sdk-release.qnsdk.com/qiniu-web-player-1.2.3.js
<script charset="utf-8" type="text/javascript" src="https://sdk-release.qnsdk.com/qiniu-web-player-1.2.3.js"></script>
引到项目中即可
二。展示demo
html 部分
<div id="player" style=" 640px; height: 480px;"> </div>
javescript 部分
window.onload = function () { loadPlay() } function loadPlay() {
const url = "http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4" player = new QPlayer({ url: url, container: document.getElementById("player"), }) player.on("ready", handleReady); }
此时可以展示出基础画面
三。增加进度条上的视频帧缩略图
先以固定图片作为代替。
javascript
const imgbase64 = "data:image/jpg;base64,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" function getVideoImage(e, time) {
// time 是当前鼠标悬浮的时间点。秒 const jindutiao = document.getElementsByClassName('qplayer-timetooltip')[0] const imgBase = imgbase64 var thubImg = document.getElementById("thubImg"); if(thubImg) { thubImg.remove(); } var img = new Image() img.src = imgBase img.id = "thubImg" img.className = "thubImg" img.style.top = "-80px" jindutiao.appendChild(img) }
css
<style> [data-balloon]:hover > .thubImg{ opacity: 1 !important; pointer-events: auto; transform: translate(-50%, 0); } .thubImg { content: attr(data-balloon); bottom: 100%; left: 50%; margin-bottom: 11px; -webkit-transform: translate(-50%, 10px); transform: translate(-50%, 10px); -webkit-transform-origin: top; transform-origin: top; opacity: 0; pointer-events: none; transition: all 0.1s ease-out 0.1s; position: absolute; z-index: 1; width: 134px; height: 76px; } </style>
将七牛云sdk,下载到本地。进行修改源码
搜索 handleHoverTooltips 。增加一下代码
// *** 当鼠标移动到进度条时
getVideoImage(e, $o(t))
此时效果已经有了缩略图。
四。根据时间获取视频帧的缩略图
C# 通用,利用插件ffmpeg.exe
#region 生成视频缩略图 [HttpGet("GenThupImage")] public QueryResultModel GenThupImage(int index) { QueryResultModel returnValue = new QueryResultModel(); try { // 基本文件路径 string url = @"E:300.researchWeb_Vue_Componentsdemo_Video_qiniu ool"; string videoName = "test"; string base64 = ""; string DirectoryPath = videoName + @"thubDir"; // 判断是否有帧数图片文件夹 if (!Directory.Exists(url + DirectoryPath)) { Directory.CreateDirectory(url + DirectoryPath); } //判断是否有当前秒数的图片 string ImagePath = url + DirectoryPath + index+"_test" + ".jpg";//为生成的缩略图所在的路径 if (System.IO.File.Exists(ImagePath)) // 该帧图片存在时 { base64 = getImgBase64(ImagePath); } else { // 该帧图片不存在时 string ffmpegPath = url + "ffmpeg.exe";//为ffmpeg的全路径 string oriVideoPath = url + videoName+".mp4";//为视频的全路径 int frameIndex = index;//为帧处在的秒数 int thubWidth = 96;//为缩略图的宽度 int thubHeight = 54; //为缩略图的高度 string command = string.Format(""{0}" -i "{1}" -ss {2} -vframes 1 -r 1 -ac 1 -ab 2 -s {3}*{4} -f image2 "{5}"", ffmpegPath, oriVideoPath, frameIndex, thubWidth, thubHeight, ImagePath); base64 = Execute(command, ImagePath); } returnValue.Data = base64; return returnValue; } catch (Exception ex) { returnValue.Code = QueryActionResult.ServerError; returnValue.Message = ex.Message; return returnValue; } } /// <summary> /// 调用cmd命令 /// </summary> /// <param name="str"></param> private string Execute(string str, string ImagePath) { System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动 p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息 p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息 p.StartInfo.RedirectStandardError = true;//重定向标准错误输出 p.StartInfo.CreateNoWindow = true;//不显示程序窗口 p.Start();//启动程序 //向cmd窗口发送输入信息 p.StandardInput.WriteLine(str + "&exit"); p.StandardInput.AutoFlush = true; //获取cmd窗口的输出信息 string output = p.StandardOutput.ReadToEnd(); p.WaitForExit();//等待程序执行完退出进程 p.Close(); return getImgBase64(ImagePath); } public string getImgBase64(string imgPath) { Bitmap bmp = new Bitmap(imgPath); MemoryStream ms = new MemoryStream(); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); byte[] arr = new byte[ms.Length]; ms.Position = 0; ms.Read(arr, 0, (int)ms.Length); ms.Close(); return Convert.ToBase64String(arr); } #endregion
testthubDir 是帧图片保存文件夹
ffmpeg.exe 是取帧缩略图的插件
test.mp4 是源视频
文件夹中的内容。
此时可以根据接口,传递当前时间,返回当前的缩略图。
此时只是第一步。刚写到这里。
接下来打算按照b站的思路。
把一个视频分成5段。
然后截出500张图。
然后拼成5个雪碧图。
最多5个请求即可返回所有的缩略图,然后进行展示,就可以达到你想要到效果,此段代码根据使用场景自行修改,便不发了。
getVideoImage方法中,的参数 time 是指当前鼠标悬浮的秒数。