zoukankan      html  css  js  c++  java
  • 最简单的视频网站(JavaEE+FFmpeg)

    http://blog.csdn.net/leixiaohua1020/article/details/15811977/

    本文记录一个最简单的视频网站系统。此前做过一些基于JavaEE中的 SSH (Strut2 + Spring + Hibernate)的网站系统,但是一直没有做过一个视频网站系统,所以就打算做一个“精简”的视频网站系统,以方便以后测试以及学习使用。本视频网站支持直播(通过RTMP实现)和点播(通过HTTP实现)。为了保持精简,这个视频网站系统仅制作了网络视频的管理功能(增删改查),以及相关的参数配置功能。由于自己在JavaEE方面没有深入学习过,所以这个系统有部分功能还没搞完,以后有时间再慢慢完善。

    简介

    架构

    系统前台显示采用了Div + CSS+ Javascript技术。其中前台显示用了一些Javascript插件,例如说生成旋转灯笼式效果的CloudCarousel,生成导航菜单的 ddsmoothmenu,用于表单验证的jQuery Validation Engine等等。其中视频播放器用了FlowPlayer(包含了RTMP插件)来支持HTTP的点播和RTMP的直播。按理说视频文件上传的时候可以使用Ajax实现,但是考虑工作比较繁琐,所以暂时还是使用直接文件上传的方式。

    系统的后台使用了JavaEE系统中最传统的三层架构:Action层,Service层以及DAO层。其中Action层使用了Struts2框架,用于处理前台页面传来的请求;DAO层使用了Hibernate框架,用于和数据库的交互。Spring框架则用于将Action层,Service层以及 DAO层整合起来。系统的前后台交互主要使用了JSTL标签和EL表达式。此外考虑到国际化方面的要求,采用了Struts2的i18n方式,将所有页面上的文字都抽取坐来保存到单独的文件中,这样就可以实现多种语言的显示。

    系统开始运行后,会开启两个线程VideoThumbnailThread和VideoTranscoderThread。 VideoThumbnailThread用于截取视频的缩略图,VideoTranscoderThread则用于转码上传的视频。这两个线程都是通过调用ffmpeg.exe完成相应的功能。

    此外,系统中还包含了查看媒体信息的功能。该功能通过调用MediaInfo.dll完成,不再详述。

    整个系统的框架如下图所示,后文中再详细记录每部分的功能。

    效果

    系统主要包含了以下几个页面:

    主页(index.jsp):进入系统的第一个页面。 
    视频列表(videolist.jsp):列表显示视频资源的页面。按照视频源的类型的不同可以分为点播(VOD)视频列表和直播(Live)视频列表。 
    视频编辑(videoedit.jsp):编辑视频资源的页面。按照视频源的类型的不同可以分为点播(VOD)编辑和直播(Live)编辑。按照操作的不同可以分为添加(Add)和编辑(Edit)。 
    视频内容(videocontent.jsp):查看视频的内容的页面。按照视频源的类型的不同可以分为点播(VOD)视频内容和直播(Live)视频内容。 
    设置(configure.jsp):设置页面。用于配制系统的参数。 
    关于(about.jsp):显示系统相关的一些信息的页面。
    首页

    网站首页的如下图所示。Logo位于左上角,菜单栏位于右上角。为了美观一些,页面上方做了一个灯箱效果的特效,随机显示一些视频的缩略图。页面下方则分别列出“点播列表”和“直播列表”中最近添加的几个视频。

    点播列表

    点播列表页面如下图所示。在该页面中,可以对点播视频进行简单的管理:查看内容,添加,修改以及删除。

    直播列表

    点播列表页面如下图所示。直播列表实质上使用了和点播列表相同的页面。在该页面中,可以对直播视频进行简单的管理:查看内容,添加,修改以及删除。

    视频内容页面

    视频内容页面如下所示。该页面中包含了一个FlowPlayer播放器,该播放器用于播放视频内容。

    点播视频内容页面如下所示。

    直播视频内容页面如下所示。尽管表面上看点播和直播页面完全相似,但是实际上点播和直播的机制是不一样的。点播依靠的是HTTP渐进式下载,而直播依靠的是FlowPlayer的RTMP组件。

    视频添加页面

    点播视频添加页面如下所示。该页面用于上传一个点播视频。“名称”输入框用于指定视频的名称,“文件”用于指定上传的视频文件,“简介”可以指定针对该视频的一段简介。其中,“名称”和“文件”两个输入框为必填项,否则无法提交该页面的表单。

    直播视频添加页面如下所示。从图中可以看出直播和点播的添加页面很类似。它们的不同在于:点播是上传一个视频文件,而直播是指定一个URL(目前该URL只支持RTMP)。和点播类似,“名称”和“URL”两个输入框为必填项,否则无法提交该页面的表单。

    视频编辑页面

    点播视频编辑页面如下所示。该页面用于编辑已经完成上传的点播视频的信息。

    直播视频编辑页面如下所示。该页面用于编辑直播视频的信息。

    配置

    系统的配置页面如下图所示。该页面用于配置系统的各种设置(以转码设置为主)。每次配置完成后重启系统后设置生效。包含以下参数。

    • 视频编码器:转码使用的视频编码器,默认值为“libx264”。
    • 视频码率 (bps) :视频编码的码率(单位为bps),默认值为500000(500kbps)。
    • 视频帧率 (fps) :视频编码的帧率(单位为fps),默认值为25。
    • 音频编码器:转码时候使用的音频编码器,默认值为“libmp3lame”。
    • 音频采样率 (Hz) :音频编码的采样率(单位为Hz),默认值为22050(22.05kHz)。
    • 音频码率 (bps) :音频编码的码率(单位为bps),默认值为64000(64kbps)。
    • 视频宽 (pixel) :转码后视频的宽(单位为pixel),默认值为640。
    • 视频高 (pixel) :转码后视频的高(单位为pixel),默认值为360。
    • 使用水印:选择转码后的视频是否加水印。如果该选项选择“是”,则会在转码后的视频中添加水印。
    • 水印文件路径:水印文件的路径,此处为文件相对于网站根目录的路径,默认为“watermark/svw.png”。
    • 水印位置-x坐标 (pixel) :水印在视频中的位置——x坐标(单位为pixel),默认值为5。
    • 水印坐标-y坐标 (pixel) :水印在视频中的位置——y坐标(单位为pixel),默认值为5。
    • 保持宽高比并且填充黑边:选择转码后是否保持宽高比。如果该选项选择“是”,则转码后的视频会保持宽高比,并且当输入和输出视频宽高比不一样的时候,会在输出视频中添加黑边。如果该选项选择“否”,则转码后的视频会拉伸成输出分辨率。
    • 输出视频封装格式:输出视频的封装格式,默认为“flv”。
    • 视频截图位置 (sec) :获取视频缩略图的位置(单位为sec),默认为5sec。该默认值的含义是获取视频第5秒处的视频帧作为视频的缩略图。
    • 上传视频存放文件夹:用于存放上传的视频文件,默认值为“videoori”。
    • 转码视频存放文件夹:用于存放转码的视频文件,默认值为“video”。
    • 视频截图存放文件夹:用于存放视频的截图,默认值为“videothumbnail”。

    MediaInfo信息

    MediaInfo信息位于视频内容页面中,在默认的情况下是不显示的。通过修改网页中代码可以显示视频的MediaInfo信息。

    转码前文件信息如下图所示,从图中可以看出转码前的文件格式是MPEG-PS,视频编码为MPEG-1,音频编码为MP2。

    转码后文件信息如下图所示,从图中可以看出转码前的文件是FLV格式的,视频编码为H.264,音频编码MP3。

    多国语言

    本系统支持多国语言。选择右上角菜单的“语言”->“English”可以将系统切换到英文。英文界面如下图所示。

    英文版的视频点播列表如下图所示。

    英文版的视频内容页面如下图所示。

    英文版的配置界面如下图所示。

    网站部分

    下面简单记录一下网站部分的关键源代码。分成三个部分:数据库、前台和后台。

    数据库

    系统包含了4张表:video,videostate,category,configure。下面简单记录每个表的含义。

    Video表

    Video表用于存储视频记录。每一个视频对应Video表中的一条记录。该表中的字段如下表所示。

    image

    备注

    *其中点播视频的URL为视频文件的相对路径。

    下面例举Video表中的几项和URL有关数据(受限于篇幅,省略其它字段)。

    image

    Videostate表

    Videostate表用于存储视频的状态。该表中字段如下表所示。

    image

    目前按照执行的顺序定义了4种状态:等待上传,等待截图,等待转码,完成。其中“CSS样式”用于辅助显示视频的状态。该表的内容如下

    image

    Category表

    Category表用于存储视频的分类。该表可以用于确定视频的分类,目前还没有做太多开发。

    image

    Configure表

    Configure表用于存储系统配置信息。该表中字段如下表所示。

    image

    该表的内容如下。

    image

    前台


    前台部分没有太多可以记录的,基本上都是各种DIV和CSS的调整。其中使用了较多的JSTL标签以及EL表达式。此外使用了Struts2标签用于支持国际化。基本的jsp页面只有6个:

    index.jsp:首页。 
    videolist.jsp:视频列表——直播视频列表,点播视频列表。 
    videoedit.jsp:视频编辑——直播视频添加,直播视频编辑,点播视频添加,点播视频编辑。 
    videocontent.jsp:视频内容——直播视频内容,点播视频内容。 
    configure.jsp:配置页面。 
    about.jsp:关于页面。

    除了基本页面之外,还有一些辅助页面:

    cfooter.jsp:页脚。 
    cheader.jsp:标题栏。 
    csidebar_recent.jsp:侧边栏(最近添加)。 
    error.jsp:错误页面。
    FlowPlayer播放器

    前台页面中用于视频播放的播放器是FlowPlayer。FlowPlayer播放器安装有3个步骤: 
    (1)包含FlowPlayer的Js文件

    <script type="text/javascript" src="videoplayer/flowplayer-3.2.8.min.js"></script>

    (2)添加一个<a>标记

    <a href="http://www.mywebsite.com/myVideo.flv"  
           style="display:block;425px;height:300px;"  
           id="player">  
        </a>

    (3)添加一段Javascript代码,其中要包含FlowPlayer的Swf文件

    <script language="JavaScript"> 
      flowplayer("player", "path/to/the/flowplayer-3.2.18.swf");  
    </script>

    FlowPlayer通过HTTP播放点播视频文件的源代码如下所示。${video.url}中保存了视频的相对URL。

    <a id="player" href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/${video.url}"> 
    </a> 
    <script> 
       flowplayer("player", "videoplayer/flowplayer-3.2.8.swf");  
    </script>

    FlowPlayer 通过RTMP播放直播视频文件的示例代码如下所示。${video.url}中保存了视频的URL。播放RTMP的时候用到了FlowPlayer的 RTMP Plugin。需要注意的是,RTMP的URL需要拆分开来分别填到不同的位置。在这里通过split(‘/’)函数按照“/”将字符串分离为字符串数组。然后将“protocol://server/app”填至plugins的netConnectionUrl字段,playpath填至clip的 url字段。

    复制代码
    复制代码
    <a id="player"> 
    </a> 
    <!-- Parse RTMP URL --> 
    <script> 
    str='${video.url}';  
    arr=str.split('/');  
          //rtmp://server/app/playpath  
    protocol=arr[0];  
    server=arr[2];  
    app=arr[3];  
    playpath=arr[4];  
    lowplayer("player", "videoplayer/flowplayer-3.2.8.swf",{   
            clip: {   
              //scaling:'orig',  
              url: playpath,  
              provider: 'rtmp',  
              live:'true'  
            },    
            plugins: {    
               rtmp: {    
                 url: 'videoplayer/flowplayer.rtmp-3.2.8.swf',    
                 netConnectionUrl: protocol+'//'+server+'/'+ app  
               }   
           }   
        });  
    

    script>

    复制代码
    复制代码
    后台

    后台部分采用了JavaEE的SSH (Struts2 + Spring + Hibernate)的三层架构,其中的代码不再详细记录。三层分别为Action层、Service层和DAO层。其中Action层采用了 Struts2框架,DAO层采用了Hibernate框架,而Spring则整合了这三个层面。

    BaseService/BaseDAO

    SSH 三层架构虽然在解耦合方面做得很好,但是却导致开发起来非常繁琐,严重降低了开发的速度。为了方便起见,本系统中在Service层编写了 BaseService用于完成通用的Service操作;在DAO层也编写了BaseDAO用于完成通用的DAO操作。这样除非有特殊需求,一般情况下只要调用BaseService中的方法就可以完成各种基本的操作。BaseService包含的接口如下所示。

    复制代码
    复制代码
    /** 
    * 最简单的视频网站 
    * Simplest Video Website 
    * 
    * 雷霄骅 Lei Xiaohua 
    * 
    * leixiaohua1020@126.com 
    * 中国传媒大学/数字电视技术 
    * Communication University of China / Digital TV Technology 
    * http://blog.csdn.net/leixiaohua1020 
    * 
    * 本程序是一个最简单的视频网站视频。它支持 
    * 1.直播 
    * 2.点播 
    * This software is the simplest video website. 
    * It support: 
    * 1. live broadcast 
    * 2. VOD 
    */ 
    package service;  
    

    import java.util.List;

    /**

    • @author 雷霄骅
    • 对Object的Service
    • 包含了一些通用的方法
      /
      public interface BaseService {
      /
      *
      * 保存一个对象
      * @param object 一个对象
      /
      public void save(Object object);
      /
      *
      * 更新一个对象
      * @param object 一个对象
      /
      public void update(Object object);
      /
      *
      * 删除一个对象
      * @param object 一个对象
      /
      public void delete(Object object);
      /
      *
      * 根据ID读取一个指定名称的对象
      * @param targetName 对象的名称
      * @param id 对象的ID
      * @return 一个对象
      */
      public Object ReadByID(String targetName,int id);

    @SuppressWarnings("rawtypes")
    /**
    * 获取指定类型的所有对象
    * @param targetName 对象类型名称
    * @return 对象的列表
    */
    public List ReadAll(String targetName);

    @SuppressWarnings("rawtypes")
    /**
    * 根据“属性-值”获取多个指定类型的对象
    * @param targetName 对象类型名称
    * @param propertyName 对象中属性的名称
    * @param propertyValue 对象中属性的值
    * @return 对象的列表
    */
    public List ReadByProperty(String targetName,String propertyName,Object propertyValue);

    /**
    * 根据“属性-值”获取一个指定类型的对象
    * @param targetName 对象类型名称
    * @param propertyName 对象中属性的名称
    * @param propertyValue 对象中属性的值
    * @return 一个对象
    */
    public Object ReadSingle(String targetName,String propertyName,Object propertyValue);

    /**
    * 获取多个指定类型的对象,可以限定获取对象数目的多少,并且根据特定的属性进行排序。
    * @param targetName 对象类型名称
    * @param propertyName 对象中属性的名称,用于排序
    * @param num 结果对象列表的最大数目
    * @param order 排序方式,可以选择“asc”或者“desc”
    * @return 对象的列表
    */
    public List ReadLimitedByOrder(String targetName,String propertyName,int num,String order);

    /**
    * 获取指定类型的对象的数量。
    * @param targetName 对象类型名称
    * @return 数量
    /
    public int ReadCount(String targetName);
    /
    *
    * 根据“属性-值”为条件,获取指定类型的对象的数量。
    * @param targetName 对象类型名称
    * @param propertyName 对象中属性的名称
    * @param propertyValue 对象中属性的值
    * @return 数量
    /
    public int ReadCountByProperty(final String targetName,String propertyName, Object value);
    /
    *
    * 两个功能:
    * 1.根据“属性-值”获取多个指定类型的对象
    * 2.限定获取对象数目的多少,并且根据特定的属性进行排序。
    * @param targetName 对象类型名称
    * @param readpropertyName 对象中属性的名称,用于获取对象
    * @param readvalue 对象中属性的值
    * @param orderpropertyName 对象中属性的名称,用于排序
    * @param num 结果对象列表的最大数目
    * @param order 排序方式,可以选择“asc”或者“desc”
    * @return
    */
    public List ReadByPropertyAndLimitedByOrder(final String targetName, final String readpropertyName,
    final Object readvalue,final String orderpropertyName, final int num, final String order);

    }

    复制代码
    复制代码

    FFmpeg部分

    截取缩略图线程和转码线程

    系统在启动后会开启两个线程:VideoThumbnailThread和VideoTranscoderThread。其中 VideoThumbnailThread线程会不停的检测需要截取缩略图的视频,调用相应的FFmpeg命令截取缩略图;VideoTranscoderThread线程会不停的监测需要转码的视频,调用相应的FFmpeg命令转码视频。何以确定视频是否需要截取缩略图以及是否需要转码?这是通过video表中的videostateid字段来标识的。视频开始上传后,该视频记录会被标记为“等待上传”(第1步);上传完毕后,该视频记录会被标记为“等待截图”(第2步);截图完毕后,该视频记录会被标记为“等待转码”(第3步);转码完毕后,该视频记录会被标记为“完成”(第4步)。VideoThumbnailThread会不停地检查系统中“等待截图”的视频,截图完成后将视频标记为“等待转码”;VideoTranscoderThread会不停地检查系统中“等待转码”的视频,转码完成后将视频标记为“完成”。

    FFmpeg和Java的整合

    FFmpeg和Java整合的过程中有以下几个需要注意的地方:

    (1)路径的处理

    FFmpeg处理视频的时候需要用到绝对路径,所以涉及到绝对路径获取的问题。使用ServletContext的getRealPath("/")方法可以获得当前Web应用根目录的绝对路径。例如在自己的电脑上下述代码可以获得Web应用的据对路径:

    ServletContext servletContext;  
    System.out.println(servletContext.getRealPath("/"));

    执行完后输出为:

    D:MyEclipseWorkspace.metadata.me_tcatwebappssimplest_video_website

    相对路径中的URL中路径的分隔采用“/”(正斜杠,Unix系统使用),而上述代码中路径的分隔采用“”(反斜杠,Windows系统使用)。如果把相对文件路径和绝对目录路径拼接起来传递给FFmpeg的话,FFmpeg是可以识别的,但是这样一来路径中一会“/”一会“”会给人一种很别扭的感觉,因此可以使用String的replace()方法将“”统一替换为“/”,这样就整齐多了。例如下面代码:

    ServletContext servletContext;  
    System.out.println(servletContext.getRealPath("/").replace('\', '/'));

    执行完后输出为:

    D:/MyEclipseWorkspace/.metadata/.me_tcat/webapps/simplest_video_website/

    (2)FFmpeg命令行的调用

    FFmpeg命令行的的调用可以分成两个步骤:

    (a)生成符合设置的命令

    这一步骤实际上就是一个简单的字符串拼接的过程。根据配置的参数拼接成相应的转码命令。需要注意的是,在输入和输出的文件路径两边要加上双引号。否则当文件路径中包含空格的时候,会导致路径解析错误。

    (b)调用命令行

    调用命令行使用Runtime.getRuntime().exec(cmdstr)方法就可以了。其中cmdstr常见的格式有两种:

    cmd /c {FFmpeg Command}  
    cmd /c start {FFmpeg Command}

    第一种格式是在本窗口中直接执行命令,第二种格式是新打开一个窗口执行命令。第一种方法我在JavaEE环境中测试有问题,而且不弹出窗口不便于调试,所以使用第二种执行方法。

    (c)等待调用的命令行执行完毕

    Runtime.getRuntime().exec()在调用命令后就直接返回当前线程了。这不符合实际的需求。实际中需要系统完成FFmpeg转码工作后,才能做下一步操作。可以用Process的waitFor()方法阻塞当先线程直至调用程序运行结束。

    截取缩略图命令

    FFmpeg截取缩略图命令如下:

    ffmpeg -y -i "ourtime.flv" -ss 5 -s 220x110 -f image2 -vframes 1 "thumbnail.jpg"

    参数含义如下:

    -y:输出文件重名的时候,自动覆盖。 
    -i:输入文件路径(可以是相对路径或者绝对路径)。 
    -ss:截取缩略图的时间点,这里是5s处。 
    -s:输出缩略图的分辨率,这里是220x110。 
    -f:输出文件格式,这里的image2代表文件格式为图片。 
    -vframes:输出视频帧的个数,这里是1。 
    最后一个参数为输出的缩略图文件路径。
    转码命令

    FFmpeg转码命令如下:

    ffmpeg -y -i "ourtime.flv" -vcodec libx264 -b:v 500000 -r 25 -acodec libmp3lame -b:a 64000 -ar 22050 -vf scale=w=640:h=360:force_original_aspect_ratio=decrease,pad=w=640:h=360:x=(ow-iw)/2:y=(oh-ih)/2[aa];movie=svw.png[bb];[aa][bb]overlay=x=5:y=5 "ourtime_convert.flv"

    参数含义如下:

    -y:输出文件重名的时候,自动覆盖。 
    -i:输入文件路径(可以是相对路径或者绝对路径)。 
    -vcodec:视频编码器,这里是libx264。 
    -b:v:视频码率,这里是500000bps。 
    -r:视频帧率,这里是25fps。 
    -acodec:音频编码器,这里是libmp3lame。 
    -b:a:音频码率,这里是64000bps。 
    -ar:音频采样率,这里是22050Hz。 
    -vf:滤镜,用于图像拉伸以及水印叠加。 
    最后一个参数为输出的视频文件路径。

    Filter(滤镜)配置

    几句话介绍一下Filter的配置:

    • Filter配置参数使用在FFmpeg的-vf参数之后
    • Filter 之间可以使用“,”连接,连接之后前一个Filter的输出作为后一个Filter的输入。几个Filter构成一个FilterChain(滤镜链),每个FilterChain以“;”结尾。几个Filter Chain可以构成一个FilterGraph(滤镜图)。可以在Filter的Pad上添加“标签”用于连接其它Filter,Filter标签的形式为“[xx]”(其中“xx”可以随意写一些字符,只要可以起到标记作用就可以了)。
    • Filter的可以使用多个参数,参数之间使用“:”分割。

    下面分别记录几个滤镜的使用方法。

    【scale滤镜】

    scale滤镜使用libswscale对图像进行拉伸。它的参数含义如下:

    w:输出图像的宽。 
    h:输出图像的高。
    force_original_aspect_ratio:保持视频宽高比的方法,可以使用如下值:(1)disable——不保持宽高比;(2)decrease——需要的时候降低宽或者高;(3)increase——需要的时候提高宽或者高。

    有关force_original_aspect_ratio可以举个例子:输入视频分辨率是1920x800,设置滤镜为:

    scale=w=640:h=360:force_original_aspect_ratio=decrease

    输出的视频分辨率为640x266。 
    【pad滤镜】 
    pad滤镜用于给拉伸后的图像加“黑边”。经过scale滤镜处理之后,视频的宽一定小于等于640,而视频的高一定小于等于360,此时需要使用pad滤镜填充视频的两边(上下或者是左右),保证输出的视频的分辨率为640x360。 
    Pad滤镜有四个基本的参数:

    w:填充后视频的宽度 
    h:填充后视频的高度 
    x:输入视频的左上角在填充后视频中的x坐标 
    y:输入视频的左上角在填充后视频中的y坐标

    一个基本的如法如下所示:

    pad=w=640:h=480:x=0:y=40

    上述滤镜将视频填充为640x480,同时将输入视频的左上角放在(0,40)的位置上。 
    在给视频加黑边的过程中,需要把输入的视频放在填充后视频的中央,而pad滤镜中输入视频的位置是以左上角来确定的,因此确定输入视频的左上角的坐标是一个比较麻烦的事。对此,pad滤镜提供了以下几个变量。

    iw:输入视频的宽 
    ih:输入视频的高 
    ow:输出视频的宽 
    oh:输出视频的高

    通过上述几个变量,可以得知如果想把输入视频放在填充后视频的中央,输入视频的x坐标应该为(ow-iw)/2,y坐标应该为(oh-ih)/2。 
    【movie滤镜】 
    Movie 滤镜属于Source滤镜,它用于读取水印图片文件(一般情况下是一个PNG文件)。有关movie滤镜有一个地方需要特别注意:它在Windows下似乎不支持输入路径为绝对路径。因为Windows下文件的绝对路径通常为“D: est......watermark.png”,即其中开头的盘符后面跟着一个“:”。“:”在Filter中是一个特殊字符,会被解析成参数的分隔符,从而导致输入的绝对路径被解析为2个参数,最后造成错误。这个问题当时我调试了半天仍然没有得到解决。因此,Windows下使用movie滤镜的时候,需要保证水印文件就在当前的工作目录中,才能正常运行。 
    【overlay滤镜】 
    Overlay滤镜用于叠加两路输入。具体到本文的系统中就是叠加水印文件到视频文件上。它常用的有两个参数:

    x:水印左上角的x坐标 
    y:水印左上角的y坐标


    经过上述几个滤镜的处理,最终就可以得到一个分辨率为640x360,保持宽高比(加黑边),叠加过水印的视频。

    项目主页

    Simplest Video Website

    开源中国:http://git.oschina.net/leixiaohua1020/simplest_video_website

    安装步骤 
    1.安装JavaEE环境: 
    (1)下载安装JDK 
    (2)下载安装Tomcat 
    (3)下载安装MySQL 
    2.FFmpeg 
    (1)下载并且解压缩FFmpeg可执行程序 
    (2)把FFmpeg的bin目录(其中包含ffmpeg.exe)添加至系统的"path"环境变量(重要,这样才可以在系统任意目录中使用ffmpeg命令) 
    3.复制程序 
    (1)修改WebrootWEB-INFclasseshibernate.cfg.xml中数据库的用户名和密码 
    (2)拷贝WebRoot目录至Tomcat的webapps目录,重新取个名字(例如"svw") 
    (3)在MySQL中创建数据库"svw",在其中执行svw.sql,创建数据库中的表,并且添加测试数据 
    4.启动Tomcat 
    5.使用浏览器访问http://localhost:8080/svw

    http://www.cnblogs.com/xkfz007/p/4517966.html

    ♣FFmpeg是什么?

    FFmpeg组成

    下载工具

    ♣安装FFmpeg

    ♣应用到j2ee项目


    前言:学习视频编码,一定要知道雷霄骅(leixiaohua1020)的专栏 ,伟大的程序员,26岁去世。雷霄骅---巨星陨落。此文多为摘录自ffmpeg的文档。

    官网:https://www.ffmpeg.org/

    github地址:https://github.com/FFmpeg/FFmpeg

    1.FFmpeg是什么?

      引用百度百科,FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
      FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。
    2.FFmpeg组成

        构成FFmpeg主要有三个部分,

        2.1第一部分是四个作用不同的工具软件,分别是:ffmpeg.exe,ffplay.exe,ffserver.exe和ffprobe.exe。

    • ffmpeg.exe:音视频转码、转换器
    • ffplay.exe:简单的音视频播放器
    • ffserver.exe:流媒体服务器
    • ffprobe.exe:简单的多媒体码流分析器

        2.2第二部分是可以供开发者使用的SDK,为各个不同平台编译完成的库。如果说上面的四个工具软件都是完整成品形式的玩具,那么这些库就相当于乐高积木一样,我们可以根据自己的需求使用这些库开发自己的应用程序。这些库有:

    • libavcodec:包含音视频编码器和解码器
    • libavutil:包含多媒体应用常用的简化编程的工具,如随机数生成器、数据结构、数学函数等功能
    • libavformat:包含多种多媒体容器格式的封装、解封装工具
    • libavfilter:包含多媒体处理常用的滤镜功能
    • libavdevice:用于音视频数据采集和渲染等功能的设备相关
    • libswscale:用于图像缩放和色彩空间和像素格式转换功能
    • libswresample:用于音频重采样和格式转换等功能

        2.3第三部分是整个工程的源代码,无论是编译出来的可执行程序还是SDK,都是由这些源代码编译出来的。FFmpeg的源代码由C语言实现,主要在Linux平台上进行开发。FFmpeg不是一个孤立的工程,它还存在多个依赖的第三方工程来增强它自身的功能。在当前这一系列的博文/视频中,我们暂时不会涉及太多源代码相关的内容,主要以FFmpeg的工具和SDK的调用为主。到下一系列我们将专门研究如何编译源代码并根据源代码来进行二次开发。

    3.下载工具

       在官网上我们可以找到"Download"页面,该页上可以下载FFmpeg的工具、库和源代码等。在选择"Windows Packages"下的Windows Builds后,会跳转到Windows版本的下载页面:

       

       

       在下载页面上,我们可以看到,对于32位和64位版本,分别提供了三种不同的模式:static、shared和dev

    • static: 该版本提供了静态版本的FFmpeg工具,将依赖的库生成在了最终的可执行文件中;作为工具而言此版本就可以满足我们的需求;
    • share: 该版本的工具包括可执行文件和dll,程序运行过程必须依赖于提供的dll文件;
    • dev: 提供了库的头文件和dll的引导库;

    4.安装FFmpeg

      4.1 这里下载的是static版本,将其下载解压到E:javaEditffmpeg目录下:

      

      4.2配置环境变量:E:javaEditffmpegin;

      

      4.3 dos窗口输入 ffmpeg -version  命令,如有信息则说明成功:

      

    5.应用到j2ee项目:

      最简单的视频网站(JavaEE+FFmpeg)

  • 相关阅读:
    Jmeter 文件上传
    Jmeter数据库连接
    初探持续集成框架--->jenkins 安装及使用
    Centos7-服务命令总结
    安装--->Tomcat监控工具Probe
    为什么要用Spring IOC
    业务接口设计总结
    Hessian HelloWorld
    日期控件的使用,My97DatePicker
    idea 启动debug时 throw new ClassNotFoundException(name);
  • 原文地址:https://www.cnblogs.com/jpfss/p/10880542.html
Copyright © 2011-2022 走看看