前言

不得不吐槽一下咯,年终奖发了不到半个月的工资,心醉了,心凉了发火!不过技术知识是属于自己的东西,有新的想法,学到新的知识还是的总结出来,和大家分享分享!

最近一直在忙公司的项目,主要针对视频播放这一块,说具体点是关于flowplayer的这一块。上一篇《基于web的视频在线编辑》已经简单总结了一下flowplayer的强大功能。今天的主角就是基于flowplayer的视频预览,如何实现?

大家在平时观看视频的视频网站中,比如优酷,爱奇艺,腾讯视频等,鼠标移动至播放条区域的时候,大家可以看到会弹出小的视频预览图片,这样子就可以给用户很好体验,至少可以知道前后播放的内容。最近公司业务需要,就不得不研究了。

本文将从三个方面进行总结

一、设计与逻辑(最重要)

二、优化拓展

三、代码

特别说明:本设计针对flowplayer版本为6.0版本,低于6.0版本在本设计中不适用,后面会简单说到在flowplayer的5.0版本如何设计的问题,整个设计会复杂很多。

一、设计与逻辑

首先有三个问题

(1)鼠标移到flowplayer的播放条上如何获取对应的时间。

(2)在对应的时间又如何获取到该时间点上的视频的缩略图。

(3)如何显示的样式问题,像爱奇艺的缩略图显示一排在播放器区域内显示。

第一个问题

在flowplayer6.0的版本中,flowplayer.min.js其实已经实现获取时间的功能,在官网的demo中,只要鼠标把移至播放的时间轴上,就会出现一个时间。下图是我在官网上的截图。

图一

从图上可以看到,鼠标移至00:02时,出现一个div,显示时间,可以在firebug的调试中找到该<div>,其实是,可以针对该div入手。首先,我们可以<divclass="fp-timeline-tooltip fp-tooltip">在里面再创建两个<div>。创建之后形式如下

<div class="fp-timeline-tooltip fp-tooltip"><div class="fp-thumbnails"></div><div class="fp-seektime" id="fp-seektime"></div></div>

其中, <div class="fp-thumbnails"></div> 用于显示缩略图, <div class="fp-seektime" id="fp-seektime"></div> 用于显示时间,最终要实现的形式如图下

图二

这样,我们又产生一个问题了,如何创建这些元素呢?这就需要我们能够去看flowplayer.js的内部代码了,因为在加载这个flowplayer.js的时候,会内部创建<div class="fp-timeline-tooltip fp-tooltip"></div>,并将时间显示在这个div。既然这样,那可以在flowplayer.js的文件中再重新定义一个函数,这个函数循环对象为<div class="fp-timeline-tooltip fp-tooltip"></div>,创建需要的两个div

<div class="fp-thumbnails"></div>
<div class="fp-seektime" id="fp-seektime"></div>

在flowplayer.js中的html的函数之后创建,如图所示

图三

同时更改当鼠标移动时的促发的函数,原来是html函数的,现在要改为tpl函数。

图四
这样,可以解决了第一个问题了。当鼠标放在播放的进度条时,如果设置一下
<div class="fp-thumbnails">的宽度width和高度height就可以出现图二的效果啦,因为还没有获取到缩略图,所以没有缩列图显示,时间可以显示。

第二个问题

要获取缩略图,肯定要图片,这个单纯用Javascript是不可能从视频中获取对应时间的图片的,下面会用到专注于多媒体处理的ffmpeg来将这个视频的关键帧分解出来。

ffmpeg所用的命令

ffmpeg -i my.mp4 -filter:v framerate=1/1,scale=-1:100 -q:v 5 myvideo%d.jpg

这个命令可以将一个视频的关键帧图片全部分解出来,其中的参数可以自己查询资料。图片的命名是myvideo1.jpg,myvideo2.jpg......

其中这个framerate的值代表帧率,即相隔多少秒,截一张图,这里设置等于1,说明myvideo1.jpg就是0秒的图,myvideo2.jpg就是代表1秒的图。。。。这样子的话,就非常好办了,鼠标移到00:02时,可以取对应的myvideo3的图片,就相当于在这一秒的画面。将这个图作为<div class="fp-thumbnails"></div>的背景,也就是显示了这一张图了。

那么,问题又来了,如何获取鼠标放在进度条上的时间呢?方法也很简单哦哦!有很多种!

最简单一种是直接获取创建的<div class="fp-seektime" id="fp-seektime"></div>的值,因为这里面显示的就是时间,格式是00:00:00,需要自己重新将格式转为时间秒数,比如格式00:00:20的秒数为second=20,那么可以动态的设置

<div class="fp-thumbnails"></div>的背景为url了,例如url(./myvideo20.jpg),那么很容易就可以将对应的视频的缩略图显示出来了。

另外一种是flowplayer的原生方法,通过鼠标距离左侧的位置

var x = ev.pageX || ev.clientX,
     delta = x - common.offset(timeline).left,
     percentage = delta / common.width(timeline),
     seconds = Math.round(percentage * api.video.duration);

具体要自己了解flowplayer.js

如果显示多个缩略图又怎么办呢,显示的原理是一样的,只不过又要动态地创建多个<div>,这就涉及到样式问题,要以主缩略图为中心(即是刚才创建的那个缩略图),动态创建<div>。再可以设置一个步调step,获取每张相隔step秒的图片显示在主缩略图的左右两侧。比如鼠标移至时间是00:00:50,即现在在50秒显示的是主缩略图,则左侧可以显示的图分别是在10,20,30,40秒处的视频图,右边则是60,70,80,,,,,所以整个很重要。

其实说到这里,基本整个设计与逻辑就已经完了,剩下的是css和js的逻辑问题了,在这里我就不多说了。

第三个问题

直接看代码,主要是样式问题,如何更好地显示一排出来。

二、优化拓展

(1)尽量写成js插件形式

(2)样式外观

(3)点击缩略图,播放跳至对应时间播放

这几个是很有必要优化的

三、代码

这是一个插件的形式来的,用的时候,要在这个文件之前引入需要引入jquery文件

/*!Thumbnail image plugin for Flowplayer HTML5Copyright (c) 2015-2016, Flowplayer OyReleased under the MIT License:http://www.opensource.org/licenses/mit-license.phprequires:- Flowplayer HTML5 version 6.x or greaterrevision: $GIT_ID$
*/
(function (flowplayer,$) {"use strict";flowplayer(function (api, root) {var common = flowplayer.common,bean = flowplayer.bean,support = flowplayer.support,timeline = common.find('.fp-timeline', root)[0],timelineTooltip = common.find('.fp-timeline-tooltip', root)[0];if (support.touch || !support.inlineVideo) {return;}api.on('ready', function (ev, a, video) {// cleanupbean.off(root, '.thumbnails');common.css(timelineTooltip, {'border': '1px solid #333','color':'#fff','background-color':'#000',});var c = flowplayer.extend({}, api.conf.thumbnails, video.thumbnails);if (!c.template) {return;}var height = c.height || 80,interval = c.interval || 1,template = c.template,ratio = video.height / video.width,preloadImages = function (tmpl, max, start) {max = Math.floor(max / interval);if (start === undefined) {start = 1;}function load() {if (start > max) {return;}var img = new Image();img.src = tmpl.replace('{time}', start);img.onload = function () {start += 1;load();};}load();};if (c.preload !== false) {preloadImages(template, video.duration);}// 鼠标移动至播放条,可以显示出预览图bean.on(root, 'mousemove.thumbnails', '.fp-timeline', function (ev) {$('div.fp-pre,div.fp-next').remove();var x = ev.pageX || ev.clientX,delta = x - common.offset(timeline).left, percentage = delta / common.width(timeline),seconds = Math.round(percentage * api.video.duration);// 2nd condition safeguards at out of range retrieval attemptsif (seconds < 0 || seconds > Math.round(api.video.duration)) {return;}// enables greater interval than one second between thumbnailsseconds = Math.floor(seconds / interval);var fpthumbnails = $(timelineTooltip).find('.fp-thumbnails'),// 主缩略图的时间位置divfpseektime = $(timelineTooltip).find('#fp-seektime'),// 控制面板的宽度,视频宽度width = $(root).find('.fp-controls').width(),// 主缩略图距离视频左侧位置left = $(timelineTooltip).position().left,// 主缩略图距离视频右侧位置right = width - left - (height / ratio)-2,// 左右侧缩略图的宽度thumbwidth = c.thumbwidth || 150,// 步调,即每张缩略图显示的时间隔间step=c.step || 10;// 主缩略图的样式以及背景图片fpthumbnails.css({width: (height / ratio) + 'px',height: height + 'px',// {time} template expected to start at 1, video time/first frame starts at 0'background-image': "url('" + template.replace('{time}', seconds + 1) + "')",'background-repeat': 'no-repeat','background-size':'100% 100%','-moz-background-size':'100% 100%', /* 老版本的 Firefox */'border': '1px solid #333'});// 主缩略图的时间样式fpseektime.css({height:20 + 'px','text-align':'center','text-shadow': '1px 1px #000'});// 左侧缩略图,创建divif(left>0) {var leftnum = Math.ceil(left/thumbwidth);for(var i=0;i<leftnum;i++) {$(timelineTooltip).parent('.fp-controls').append('<div class="fp-pre"></div>'); }}// 右侧缩略图,创建divif(right>0) {var rightnum = Math.ceil(right/thumbwidth);for(var i=0;i<rightnum;i++) {$(timelineTooltip).parent('.fp-controls').append('<div class="fp-next"></div>'); }}//左侧只能显示一个缩略图位置时 if(leftnum==1){$('.fp-pre').css({'width':(left-2)+'px','height':height + 'px','position':'absolute','bottom':'30px','border-top': '1px solid #333','border-right': '1px solid #333','border-bottom': '1px solid #333','color':'#fff','background-color':'#000','overflow':'hidden','left':'1px','background-image':"url('" + template.replace('{time}', seconds + 1-step) + "')"});}else {// 出来最后一个元素的其他元素的样式设置$('.fp-pre').not(':last').each(function(i,value){$(this).css({'width':thumbwidth + 'px','height':height + 'px','position':'absolute','bottom':'30px','border': '1px solid #333','color':'#fff','background-color':'#000','left':(left - (i+1)*(thumbwidth+2)) + 'px','background-image':"url('" + template.replace('{time}', seconds + 1-(i+1)*step) + "')",/*步调*/'background-repeat': 'no-repeat','background-size':'100% 100%','-moz-background-size':'100% 100%', /* 老版本的 Firefox */});});// 设置最后一个的样式$('.fp-pre').last().css({'width':(left-(leftnum-1)*(thumbwidth+2)-1)+'px','height':height + 'px','position':'absolute','bottom':'30px','border-top': '1px solid #333','border-right': '1px solid #333','border-bottom': '1px solid #333','color':'#fff','color':'#fff','background-color':'#000','overflow':'hidden','left':'1px','background-image':"url('" + template.replace('{time}', seconds + 1-(leftnum-1)*step) + "')"});}// 右侧只有一个div时的样式if(rightnum==1){$('.fp-next').css({'width':(width-(left+(height / ratio)+2)-2)+'px','height':height + 'px','position':'absolute','bottom':'30px','border-top': '1px solid #333','border-left': '1px solid #333','border-bottom': '1px solid #333','color':'#fff','color':'#fff','background-color':'#000','left':(left + (height / ratio)+2) + 'px','overflow':'hidden','background-image':"url('" + template.replace('{time}', seconds + 1+step) + "')"});}else {// 除了最后一个的其他样式$('.fp-next').not(':last').each(function(i,value){$(this).css({'width':thumbwidth + 'px','height':height + 'px','position':'absolute','bottom':'30px','border': '1px solid #333','color':'#fff','background-color':'#000','left':(left + (height / ratio)+2 + i*(thumbwidth+2))+ 'px','background-image':"url('" + template.replace('{time}', seconds + 1+(i+1)*step) + "')",'background-repeat': 'no-repeat','background-size':'100% 100%','-moz-background-size':'100% 100%', /* 老版本的 Firefox */});});// 右侧最后一个div样式$('.fp-next').last().css({'width':(right - (rightnum-1)*(thumbwidth+2)-1)+'px','height':height + 'px','position':'absolute','bottom':'30px','border-top': '1px solid #333','border-left': '1px solid #333','border-bottom': '1px solid #333','color':'#fff','background-color':'#000','left':(left + (height / ratio)+2 + ((rightnum-1)*(thumbwidth+2))) + 'px','overflow':'hidden','background-image':"url('" + template.replace('{time}', seconds + 1 +(rightnum-1)*step) + "')"});}   });$('.fp-timeline').on('mouseout',function(){$('div.fp-pre,div.fp-next').remove();});});});})((typeof module === "object" && module.exports)? require('flowplayer'): window.flowplayer,jQuery);

在html页面中的用法

<div class="player1  no-toggle play-button"></div><div style="overflow:hidden;width:200px;height:161px;background-image:url('thumbnails/myvideo8.jpg')"><!-- <img src="thumbnails/myvideo8.jpg"> --></div></div><link rel="stylesheet" type="text/css" href="./flowplayer.quality-selector.css"><script type="text/javascript" src="./jquery-1.11.0.min.js"></script><script type="text/javascript" src="./flowplayer6.js"></script><script type="text/javascript" src="./thumbnails.js"></script><script type="text/javascript" src="./flowplayer.quality-selector.js"></script><script>$('.player1').flowplayer({adaptiveRatio:true,debug:true,autoplay:true,embed:false, clip: {title: 'Bauhausfffff',
<span style="color:#FF0000;"> //这里配置
thumbnails: {template: 'thumbnails/myvideo{time}.jpg',height: 100,thumbwidth: 150,step: 5},</span>sources: [{ type: "video/mp4",src:  "http:/host/Video/201503/20150320105047342.mp4" }]},brand:{text: "MyBrand",showOnOrigin:false}});</script>

直接上几个大图

基于flowplayer的视频缩略图的视频预览相关推荐

  1. 【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 摄像头预览数据回调接口 )

    文章目录 安卓直播推流专栏博客总结 一. Android 端数据采集涉及到的相关概念 二. Camera 预览图像尺寸设置 三. 获取摄像头采集的数据格式 安卓直播推流专栏博客总结 Android R ...

  2. 捕获iOS模拟器视频以进行App预览

    本文翻译自:Capture iOS Simulator video for App Preview Okay, so we can now submit video previews of our a ...

  3. SkeyeVSS综合安防监控Onvif、RTSP、GB28181视频云无插件直播点播解决方案之监控视频实时多屏预览

    SkeyeVSS综合安防监控Onvif.RTSP.GB28181视频云无插件直播点播解决方案之监控视频实时多屏预览 SkeyeVSS支持一分屏.四分屏.九分屏.16分屏.25分屏.36分屏等几种N*N ...

  4. android异步加载视频缩略图,Android 视频缩略图的缓存机制和异步加载

    关注微信号:javalearns   随时随地学Java 或扫一扫 随时随地学Java 在这次的工作开发项目中,涉及到一个视频缩略图的视频列表:这个在大家看来,制作视频缩略图就是两行代码就搞定的事.确 ...

  5. 基于9款CSS3鼠标悬停相册预览特效

    基于9款CSS3鼠标悬停相册预览特效里面包含九款不同方式的相册展开特效代码.效果图如下: 在线预览    源码下载 实现的代码. html代码: <div class="albums& ...

  6. Windows 7 Home Basic 的任务栏缩略图预览和Alt+Tab缩略图平铺预览功能已足够了

    网上看到许多Win7HB强开Aero特效的文章,故本人仔细看了一下Windows 7 Home Basic 中的相关功能. 也许老旧机器的确需要几个xp即可运行的类似Aero功能的VisualTool ...

  7. Android播放视频快进帧预览图完美解決方案

    播放视频快进预览图完美解決方案,使用方法如下,使用FFmpeg,不影响原有播放器, 就是先截取缩略图保存下来,快进时选用图片显示,最优方案,播放性能最好,体验完美. 参考github: https:/ ...

  8. 按照日期排序相册库(支持自定义选中图片,视频数量,支持预览,支持拍摄仿小米原生相册)

    写在前面: 此库源于公司项目需求,暂时无法提供maven地址供大家使用,此处会给源码GitHub链接代码部分修改可直接运行. 库链接:https://github.com/XMDstar/TimeAl ...

  9. 如何截取阿里云oss的视频第一帧作为预览图片

    转载于:https://blog.csdn.net/guo_qiangqiang/article/details/108865279 oss阿里云视频如何截取第一帧作为预览图片 第一步.得到视频地址 ...

  10. 在tinymce富文本中上传本地视频编辑器中不能预览的解决方案

    富文本编辑器里上传了本地视频之后,编辑区内视频不能实时预览,在调试工具中发现tinymce默认生成的是img标签. 百度一圈后发现两种解决方案, 1.修改tinymce源码 参考文章 2.自定义上传功 ...

最新文章

  1. 「模型解读」从2D卷积到3D卷积,都有什么不一样
  2. 浅析移动端网站建设前都需要考虑哪些因素?
  3. Mathematica常用命令
  4. Java 8 Lambda 表达式被编译成了什么?
  5. 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动
  6. 作者:高翔(1984-),男,国防大学信息作战与指挥训练教研部博士后,主要研究方向为体系分析与超网建模。...
  7. 远程连接管理软件 v1.0
  8. python 爬取全本免费小说网的小说
  9. 理解常量指针与指针常量?
  10. WPS如何一页一页设置页眉
  11. 磨洋工 warm-chair attrition
  12. editplus的php插件,editplus的各式插件
  13. OPCClient远程连接OPC服务器配置手册
  14. python期末考试是怎么考的_python期末考试复习
  15. 一个包含30行代码的Python项目:如何在您最喜欢的Twitcher流式传输时设置SMS通知...
  16. VSTO中Word的查找方式
  17. 带你轻松认识SSL协议中的加密套件
  18. 使用yolov3训练识别围棋死活题和围棋局面
  19. 内网服务器安装docker
  20. jbl耳机连不上android,关于蓝牙设备配对和连接的稳定性_JBL耳机_耳机评测-中关村在线...

热门文章

  1. 各位有什么超实用的生活小窍门呢?
  2. 发动机关键零部件3D视觉引导自动上料和装配系统
  3. cpolar——安全的内网穿透工具
  4. 郝兵c语言_郝斌C语言自学教程(全套)
  5. 11. 挑战500强管理职位前的苦逼生活
  6. 如何用C语言实现原码一位乘法器?这里可能有你想要的答案....
  7. 苹果id是什么格式的_苹果用户福利 | 史上最简利用itunes抓包教程只需4步!!!...
  8. 火车头伪原创php-火车头采集伪原创插件
  9. 宝峰c1对讲机写频软件_宝峰888s写频软件
  10. 【SW】利用3D打印机打印 PCB 钢网的方法