基于flowplayer的视频缩略图的视频预览

前言

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

最近一直在忙公司的项目,主要针对视频播放这一块,说具体点是关于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入手。首先,我们可以<div class="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>


直接上几个大图










本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1620855.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

php myflow,WordPress安装使用Flowplayer简易指南

本文是简单易懂的现代魔法系列文章的第二弹~ 一、Flowplayer简介FlowPlayer 是一个用Flash开发的在Web上的视频播放器&#xff0c;可以很容易将它集成在任何的网页上。支持HTTP以及流媒体传输。 最新版本为5.1.1&#xff0c;最新版本使用纯 HTML5 CSS3 实现的原生 VIDEO 标签&…

爬虫(bilibili热门课程记录)

什么是爬虫&#xff1f;程序蜘蛛&#xff0c;沿着互联网获取相关信息&#xff0c;收集目标信息。 一、python环境安装 1、先从Download Python | Python.org中下载最新版本的python解释器 2、再从Download PyCharm: Python IDE for Professional Developers by JetBrains中下…

web开源FlowPlayer视频播放器

1.原文地址&#xff1a;http://www.cnblogs.com/babycool/p/3172303.html 2.针对原作者的代码示例修正&#xff01; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> …

SSM+Flowplayer实现web项目网页看视频

功能描述&#xff1a; 用户在首页http://localhost:8080/SSM_HTTPS/&#xff0c;输入视频名&#xff0c;点击“走 你”按钮&#xff0c;跳转到视频页面&#xff0c;搜索符合你视频名的视频&#xff08;本项目中只有两个视频&#xff0c;test和test2&#xff0c;没有加任何控制…

基于oracle数据库存储过程的创建及调用

基于oracle数据库存储过程的创建及调用 教学大纲&#xff1a; PLSQL编程&#xff1a;Hello World、程序结构、变量、流程控制、游标.存储过程&#xff1a;概念、无参存储、有参存储&#xff08;输入、输出&#xff09;.JAVA调用存储存储过程. 1. PLSQL编程 1.1. 概念和目的…

2.神经网络的实现

创建神经网络类 import numpy # scipy.special包含S函数expit(x) import scipy.special # 打包模块 import pickle# 激活函数 def activation_func(x):return scipy.special.expit(x)# 用于创建、 训练和查询3层神经网络 class neuralNetwork:# 初始化神经网络def __init__(se…

7.11 SpringBoot实战 全局异常处理 - 深入细节详解

文章目录 前言一、异常分类1.1 业务异常1.2 参数校验异常1.3 通用异常兜底 二、保留异常现场2.1 请求地址2.2 请求header2.3 请求参数body2.4 构建异常上下文消息 最后 前言 全局异常处理, 你真的学会了吗&#xff1f; 学完上文&#xff0c;你有思考和动手实践吗&#xff1f;…

苹果开源iOS和macOS内核源代码 | 十一献礼

没想到&#xff0c;国庆节这天醒来一看&#xff0c;素以“封闭”闻名的苹果公司&#xff0c;竟然在GitHub上公布了旗舰操作系统的XNU内核源代码。 XNU代表的含义是“XNU is Not Unix”&#xff08;XNU不是Unix&#xff09;&#xff0c;这是一个类似Unix的内核&#xff0c;用在各…

KSZ9897 switch以及官方驱动KSZ9897

使用KSZ9897来替换QCA8337N&#xff0c; 其中官方有针对imx8mm的驱动移植的patch代码&#xff0c;注意&#xff1a;其中已KSZ9477为git名字进行命名的。 KSZ9897&#xff0c;KSZ9477驱动 https://github.com/Microchip-Ethernet/EVB-KSZ9477.git 注意下面的配置&#xff1a;…

nyoj463

九九乘法表 时间限制&#xff1a; 1000 ms | 内存限制&#xff1a; 65535 KB 难度&#xff1a; 1 描述 小时候学过的九九乘法表也许将会扎根于我们一生的记忆,现在让我们重温那些温暖的记忆,请编程输出九九乘法表. 现在要求你输出它的格式与平常的 不同啊! 是那种反过来的三角…

高性能霍尔开关CH442PN与AKM EW-632的分析对比

意瑞的高性能霍尔锁存芯片CH442PN广泛应用于电动工具&#xff0c;工业风机&#xff0c;流量计等场合。在缺芯潮下&#xff0c;针对AKM EW632的一些需求&#xff0c;CH442PN也为广大客户提供了更多选择。 以下是两者的对比分析。 相较于EW632&#xff0c;CH442PN可以支持更宽的…

nyoj 311 和995

这两个题其实是一个解法 完全背包 时间限制&#xff1a; 3000 ms | 内存限制&#xff1a; 65535 KB 难度&#xff1a; 4 描述 直接说题意&#xff0c;完全背包定义有N种物品和一个容量为V的背包&#xff0c;每种物品都有无限件可用。第i种物品的体积是c&#xff0c;价值是w。…

comp9334-proj2

对本文有疑问可以加微信 Tutor_0914联系。也可以访问我的个人辅导网站 &#xff1a; tutoryou 解析 原文 COMP9334 Project, Term 1, 2022: Priority queueing for server farms Due Date: 5:00pm Friday 22 April 2022 Version 1.01, 20 March 2022 Updates to the projec…

AWR2243

TDA2xx-AWRx243 TI毫米波板&#xff08;代完善更新和作者的继续研究&#xff09; 1、安装mmwave studio和驱动&#xff08;链接&#xff1a; https://download.csdn.net/download/weixin_42501561/19775644 &#xff09; 2、设置网络端口IP地址&#xff08;如果不能更改路由器I…

Window基础命令

文章目录 查看哪些端口被禁用TCP协议删除开机启动项方案1方案2 查看哪些端口被禁用TCP协议 netsh interface ipv4 show excludedportrange protocoltcp删除开机启动项 方案1 列出所有启动项 bcdedit /enum仔细看你要删除的是哪一项&#xff08;看description&#xff09;&a…

Git企业开发控制理论和实操-从入门到深入(六)|多人协作开发

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

SpringBoot在IDEA里实现热部署

使用步骤 1.引入依赖 <!--devtools热部署--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional><scope>true</scope><versi…

Django基础6——数据模型关系

文章目录 一、基本了解二、一对一关系三、一对多关系3.1 增删改查3.2 案例&#xff1a;应用详情页3.2 案例&#xff1a;新建应用页 四、多对多关系4.1 增删改查4.2 案例&#xff1a;应用详情页4.3 案例&#xff1a;部署应用页 一、基本了解 常见数据模型关系&#xff1a; 一对一…

算法通过村第四关-栈青铜笔记|手写栈操作

文章目录 前言1. 栈的基础概要1.1 栈的特征1.2 栈的操作1.3 Java中的栈 2. 栈的实现&#xff08;手写栈&#xff09;2.1 基于数组实现2.2 基于链表实现2.3 基于LinkedList实现 总结 前言 提示&#xff1a;我自己一个人的感觉很好 我并不想要拥有你 除非你比我的独处更加宜人 --…

安利超实用的(cc协议)游戏3d模型素材网站

前方干货满满&#xff0c;建议先收藏再看哦&#xff01;为大家整理&#xff08;cc协议&#xff09;游戏3d模型素材&#xff0c;总有满足你需求的一款&#xff0c;除此之外&#xff0c;免费&#xff0c;资源质量好&#xff0c;一键打包下载&#xff0c;你还不心动吗&#xff1f;…