视频帧数缩略图

  七牛云-开源的播放器 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 是指当前鼠标悬浮的秒数。



原文地址:https://www.cnblogs.com/yasoPeng/p/12190488.html