七牛云-开源的播放器 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="width: 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.research\Web_Vue_Components\demo_Video_qiniu\tool\";
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 是指当前鼠标悬浮的秒数。
来源:https://www.cnblogs.com/yasoPeng/p/12190488.html