创建数据库:db_webavtc

创建数据表:avcategory(素材类别)

id int primary key,

pid int ,

cname varchar(255),

cmemo varchar(1000)

CREATE TABLE `avcategory` (

`id` INT(11) NOT NULL AUTO_INCREMENT,

`pid` INT(11) NOT NULL,

`cname` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`cmemo` VARCHAR(1000) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

PRIMARY KEY (`id`) USING BTREE

)

COLLATE='utf8_general_ci'

ENGINE=InnoDB

;

创建数据表:avtemplate(转码模板)

Id int primary key auto_increment,

tcTemplateId  varchar(64),

tcTemplateName varchar(64),

tcFormatType  int,//0:m3u8, 1:mp4, 2:flv

threadsNum int,//转码线程数

hlsSegmentTime int, //m3u8的切片长度(秒)

isMultiOutput int,

hasWaterMark int,

Priority int,

removeAV int,//去除视频(0),去除音频(1)

waterMark varchar(2048),//水印json串

tcTemplateDetails varchar(4096)//转码模板的json串

CREATE TABLE `avtemplate` (

`id` INT(11) NOT NULL AUTO_INCREMENT,

`tcTemplateId` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcTemplateName` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcTemplateEnglish` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcFormatType` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`isDeleted` INT(11) NULL DEFAULT '0',

`state` VARCHAR(64) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`threadsNum` INT(11) NULL DEFAULT '0',

`hlsSegmentTime` INT(11) NULL DEFAULT '10',

`tcFastMode` INT(11) NULL DEFAULT '0',

`isMultiOutput` INT(11) NULL DEFAULT '0',

`tcOutputFileCount` INT(11) NULL DEFAULT '0',

`hasWaterMark` INT(11) NULL DEFAULT '0',

`priority` INT(11) NULL DEFAULT '0',

`waterMark` VARCHAR(2048) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcTemplateDetails` VARCHAR(4096) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`createTime` DATETIME NULL DEFAULT NULL,

`removeAV` INT(11) NULL DEFAULT '0',

`isSystemReserved` INT(11) NULL DEFAULT '0',

PRIMARY KEY (`id`) USING BTREE,

INDEX `idx_by_name` (`tcTemplateName`) USING BTREE,

INDEX `idx_by_tcid` (`tcTemplateId`) USING BTREE

)

COLLATE='utf8_general_ci'

ENGINE=InnoDB

ROW_FORMAT=COMPACT

AUTO_INCREMENT=43

;

创建数据表:avassets(素材)

Id int primary key auto_increment,

avAssetsGuid varchar(255),

avSrcName  varchar(500),

avTitle  varchar(255),

avMakeFullName  varchar(500),

avType int,

avCategoryId int,

avState  int,

avTag   varchar(255),

avPoster  varchar(255),

tcTemplateId  varchar(64)

创建数据表:avtranscodetask(转码任务)

CREATE TABLE `avtranscodetask` (

`id` INT(11) NOT NULL AUTO_INCREMENT,

`tcTaskGuid` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`avAssetsGuid` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcTaskOutDir` VARCHAR(500) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcTaskOutName` VARCHAR(500) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcTaskState` INT(11) NULL DEFAULT NULL,

`tcTaskPercent` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`tcConsumeTime` INT(11) NULL DEFAULT NULL,

`tcTranscoderIP` VARCHAR(128) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

PRIMARY KEY (`id`) USING BTREE

)

COLLATE='utf8_general_ci'

ENGINE=InnoDB

;

bean

创建AVCategory

创建AVTemplate

创建AVAssets

创建AVTranscodeTask

dao

AVCategoryDaoImpl

AVTemplateDaoImpl

AVAssetsDaoImpl

AVTrancodeTaskDaoImpl

service

AVCategoryService

AVCategoryServiceImpl

AVTemplateService

AVTemplateServiceImpl

AVAssetsService

AVAssetsServiceImpl

AVTrancodeTaskService

AVTrancodeTaskServiceImpl

action

AVCategoryAction

AVTemplateAction

稍微复杂,一点一点改造

AVAssetsAction

AVTrancodeTaskAction

UI

avcategoryList.jsp

avtemplateList.jsp

avassetsMother.jsp

文件上传的组件:webuploader.js

avassetsEdit.jsp:添加素材

avassetsEdit2.jsp: 编辑素材

avassetsAddNew.action

avassetsList.jsp:素材列表

avtranscodetaskList.jsp:转码列表

配置文件

Struts.xml:            action

applicationContext.xml:   *.hbm.xml,  beans

创建数据表: ctype

CREATE TABLE `ctype` (

`ctid` INT(11) NOT NULL AUTO_INCREMENT,

`ctname` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`ctcode` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`ctno` INT(11) NULL DEFAULT NULL,

`ctdesc` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',

`csCount` INT(11) NULL DEFAULT NULL,

`pid` INT(11) NULL DEFAULT NULL,

PRIMARY KEY (`ctid`) USING BTREE

)

COLLATE='utf8_general_ci'

ENGINE=InnoDB

AUTO_INCREMENT=14

;

db_webavtc

左侧导航树

ztree

Java调用ffmpeg进行转码

import java.io.BufferedInputStream;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;

public class JavaFFmpeg extends Thread{

private boolean stoped = false;

public boolean isStoped() {

return stoped;

}

public void setStoped(boolean stoped) {

this.stoped = stoped;

}

public void run() {

// 在run方法中编写需要执行的操作

stoped = false;

openFFmpegExe();

stoped = true;

}

public static String readToString(String fileName) {

String encoding = "UTF-8";

File file = new File(fileName);

Long filelength = file.length();

byte[] filecontent = new byte[filelength.intValue()];

try {

FileInputStream in = new FileInputStream(file);

in.read(filecontent);

in.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

try {

return new String(filecontent, encoding);

} catch (UnsupportedEncodingException e) {

System.err.println("The OS does not support " + encoding);

e.printStackTrace();

return null;

}

}

public static void main(String[] args) {

System.out.println("hello,ffmpeg......");

// 在main方法(线程)中,创建线程对象,并启动线程.

JavaFFmpeg objTC = new JavaFFmpeg();

objTC.start();

String strFileContent;

while( !objTC.isStoped() ){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

strFileContent = readToString("d:/_movies/__test/ande_302.mp4.txt");

//        frame=。

int nIdxFrameStart = strFileContent.lastIndexOf("frame=");

if(nIdxFrameStart >= 0){

int nIdxFrameEnd = strFileContent.indexOf((char)0x0A, nIdxFrameStart);

if(nIdxFrameEnd > 0){

String strFrames = strFileContent.substring(nIdxFrameStart, nIdxFrameEnd);

System.out.println(strFrames);// 打印输出信息

/// out_time=00:00:02.066576

int nIdxOutTimeStart = strFileContent.indexOf("out_time=", nIdxFrameEnd);

if(nIdxOutTimeStart > 0){

int nIdxOutTimeEnd = strFileContent.indexOf((char)0x0A, nIdxOutTimeStart);

if(nIdxOutTimeEnd > 0){

String strOutTime = strFileContent.substring(nIdxOutTimeStart, nIdxOutTimeEnd);

System.out.println(strOutTime);// 打印输出信息

}

}

}

}

}

System.out.println("bye,ffmpeg......");

}

//调用其他的可执行文件,例如:自己制作的exe,或是 下载 安装的软件.

private void openFFmpegExe() {

Runtime rn = Runtime.getRuntime();

Process p = null;

try {

///ffmpeg.exe  -re  -i d:/_movies/ande10.mp4  -vcodec libx264  -acodec aac  -f flv  rtmp://192.168.0.104/hls1/test

p = rn.exec("ffmpeg431.exe -progress d:/_movies/__test/ande_302.mp4.txt  -i d:/_movies/__test/ande_302.mp4 -threads 1  -vcodec libx264 -acodec aac  -y d:/_movies/__test/ande_302_test2.mp4" );

BufferedInputStream in = new BufferedInputStream(p.getErrorStream());

BufferedReader inBr = new BufferedReader(new InputStreamReader(in));

String lineStr;

System.out.println("开始转码");

while((lineStr = inBr.readLine())!=null){

//获得命令执行后在控制台的输出信息

//System.err.println("获得命令执行后在控制台的输出信息");

/System.out.println(lineStr);// 打印输出信息

}

// 检查命令是否执行失败。

if(p.waitFor()!=0){

if(p.exitValue()==1)//p.exitValue()==0表示正常结束,1:非正常结束

System.err.println("命令执行失败!");

}

inBr.close();in.close();

} catch (Exception e) {

System.out.println("Error exec:" + e.getMessage());

}

}

}

spring定时器

spring定时器一般有两种:

TimerTask、Quartz。

1.定时执行任务的类继承TimerTask:

Java代码

public class EmailReportTask extends TimerTask{

@Override

public void run() {

System.out.println(" EmailReportTask Run... ");

}

}

2.spring的配置文件:

Xml代码

<!--  Bean  -->

<bean id="emailReportTask" class="com.fyl.spring.timertask.EmailReportTask" />

<!-- ScheduledTimerTask设置定时器属性 : period=定时器周期;delay=延迟多久启动

86400000代表24个小时;timerTask=执行定时任务的类对象  -->

<bean id="emailReportScheduleReportTask"

class="org.springframework.scheduling.timer.ScheduledTimerTask">

<property name="timerTask" ref="emailReportTask" />

<property name="period" value="2000" />

<property name="delay" value="1000" />

</bean>

<!-- Spring的TimerFactoryBean负责启动定时任务;

scheduledTimerTasks = 需要启动的定时器任务的列表-->

<bean class="org.springframework.scheduling.timer.TimerFactoryBean">

<property name="scheduledTimerTasks">

<list>

<ref bean="emailReportScheduleReportTask"/>

</list>

</property>

</bean>

<!-- ........................................ -->

<!-- ........................................ -->

<!-- ...................spring.timer..................... -->

<bean id="tcTimerTaskScheduler001" class="com.fyl.ssh.timer.TCTimerTaskScheduler">

</bean>

<bean id="scheduled_tcTimerTaskScheduler001" class="org.springframework.scheduling.timer.ScheduledTimerTask">

<property name="delay" value="1000" />

<property name="period" value="5000" />

<property name="timerTask" ref="tcTimerTaskScheduler001" />

</bean>

<bean class="org.springframework.scheduling.timer.TimerFactoryBean">

<property name="scheduledTimerTasks">

<list>

<ref bean="scheduled_tcTimerTaskScheduler001" />

</list>

</property>

</bean>

转码任务调度

查询“素材表”:等待状态

1.avassets:

avType:  0视频,1音频, 2图片

avState:  <=100等待,101:转码中, 200:转码完成, 500:转码失败

2.avassets:素材绑定模板

3.avassets:查询对应模板的详细内容,根据tcTemplateGuid

AVAssetsAction

需要添加一个属性:AVTemplateService,需要在spring配置文件中配置

4.解析模板信息

(1)String------>Class

com.alibaba.fastjson.JSON

strAVTemplateString

Class obj = JSON.parseObject(strAVTemplateString, AVTemplateDetail.class);

(2)String--->JsonArray

JSONArray templateDetailJsonArray = new JSONArray();

templateDetailJsonArray =

JSONArray.parseArray(avtTmp.getTcTemplateDetails());

for(int i = 0; i < templateDetailJsonArray.size(); i++){

AVTemplateDetail avtDetail =

JSON.parseObject(templateDetailJsonArray.getString(i) , AVTemplateDetail.class);

System.out.println(":::"+ avtDetail.getvCodec() );

}

5.准备转码

(1)先在数据表中插入一条记录

定时器,每5秒钟,执行一次

avAssets: 检测 avState==101,转码中。

如果有,跳过本地timer;否则,继续开启新转码

(2)构造转码命令,开始转码,并更新转码进度

final public static String THE_TC_FFMPEG_CMDLINE_SINGLE =

"ffmpeg431  -i %s -vcodec %s -s %dx%d -acodec %s   -f %s -y  %s";

6.获取音视频素材的媒体基本信息

基本信息、视频信息、音频信息 ...

ffprobe431 -v quiet -print_format json -show_format

-show_streams  D:\_movies\__test\ande_302_test2.mp4

ffprobe431 -i D:\_movies\__test\ande_302_test2.mp4

7.更新转码进度

(1)获取totalDuration

(2)获取实时转码进度,并转成百分比,更新数据库

(3)刷新转码列表页面

8.多码流输出

性能很高:只需要一次解码,同时进行多路编码

9.m3u8转码

切片命令行:

ffmpeg431.exe -i ande_302.mp4

-vbsf  h264_mp4toannexb -vcodec libx264 -acodec aac

-strict -2 -s 640x480  -r 30  -g 150  -start_number 0  -hls_time 5  -hls_list_size

0   -threads 1   -f hls   -y aaa.m3u8

-vbsf  h264_mp4toannexb -vcodec libx264 -acodec aac

-strict -2 -s 960x540  -r 30  -g 150  -start_number 0  -hls_time 5  -hls_list_size

0   -threads 1   -f hls   -y aaa.m3u8

-vbsf  h264_mp4toannexb -vcodec libx264 -acodec aac

-strict -2 -s 1280x720  -r 30  -g 150  -start_number 0  -hls_time 5  -hls_list_size

0   -threads 1   -f hls   -y aaa.m3u8

10.添加水印(图片、文字)

ffmpeg431.exe -i ande_302.mp4 -vf "drawtext=fontfile=simhei.ttf:text='hello, 您 好ffmpeg':x=(mod(2*n\,w+tw)-tw):y=10:fontcolor=#FF6600:fontsize=60" -f mp4 -y

ande_test_text3.mp4

11.水印:中文乱码

加上盘符后的表达式为

这个郁闷头疼:

原始语法:-vf drawtext="fontfile='d\:/_movies/__test/simhei.ttf':text=’xxx’"

Java语法:

String strXXX = “-vf drawtext=\"fontfile='d\\://_movies/__test/simhei.ttf’:text=’xxx’\"”;

Fontconfig error: Cannot load default config file

[Parsed_drawtext_0 @ 0102d840] Using "C:/WINDOWS/fonts/mingliub.ttc"

ffmpeg431  -i f:/fzavms1/fxhttp_out//__avsrc//2020/10/16/2020101614355828787ef9e22-0131-4777-b7a8-d063bc8d0b4b.mp4  -vf  "drawtext=fontfile='d\:/_movies/__test/simhei.ttf':text='284378sxxxdqqq啊啊啊':x=(mod(2*n\,w+tw)-tw):y=10:fontcolor=#FF6600:fontsize=60"  -vcodec libx264 -s 640x360 -acodec aac -threads  1  -f mp4 -y  f:/fzavms1/fxhttp_out//__tasks//2020/10/16/2020101614355828787ef9e22-0131-4777-b7a8-d063bc8d0b4b.mp4/first.mp4

ffmpeg431  -i f:/fzavms1/fxhttp_out//__avsrc//2020/10/16/2020101614355828787ef9e22-0131-4777-b7a8-d063bc8d0b4b.mp4  -vf  "drawtext=fontfile='d\:/_movies/__test/simhei.ttf':text='284378sxxxdqqq啊啊啊':x=(mod(2*n\,w+tw)-tw):y=10:fontcolor=#FF6600:fontsize=60"  -vcodec libx264 -s 640x360 -acodec aac -threads  1  -f mp4 -y  f:/fzavms1/fxhttp_out//__tasks//2020/10/16/2020101614355828787ef9e22-0131-4777-b7a8-d063bc8d0b4b.mp4/first.mp4

fastjson

String strWMJsonStr = JSON.toJSONString(objWaterMark, true);

WaterMark avtWaterMarkDetail = JSON.parseObject(strxxx , WaterMark.class);

大家好,我的第一本书正式出版了,可以在京东各大店铺抢购哦。

《FFmpeg入门详解--音视频原理及应用:梅会东:清华大学出版社》

京东自营链接:https://item.jd.com/13377793.html
京东其它链接:https://search.jd.com/Search?keyword=FFmpeg%E5%85%A5%E9%97%A8%E8%AF%A6%E8%A7%A3--%E9%9F%B3%E8%A7%86%E9%A2%91%E5%8E%9F%E7%90%86%E5%8F%8A%E5%BA%94%E7%94%A8&enc=utf-8&suggest=1.his.0.0&wq=&pvid=24e80535073b4e1f98e30a3e6963fe81

 

出书过程非常艰辛,来回校正了好几遍,后续还有FFmpeg系列的其它图书。

第一本:FFmpeg入门详解--音视频原理及应用--梅会东--清华大学出版社

第二本:FFmpeg入门详解--流媒体直播原理及应用--梅会东--清华大学出版社

第三本:FFmpeg入门详解--命令行及音视频特效原理及应用--梅会东--清华大学出版社

第四本:FFmpeg入门详解--SDK二次开发及直播美颜原理及应用--梅会东--清华大学出版社

===================================

FFmpeg入门详解之82:FFmpeg转码器Java版之ava编码相关推荐

  1. FFmpeg入门详解之6:VLC播放器简介

    VLC播放器        VLC支持多种常见音视频格式,支持多种流媒体传输协议,也可当做本地流媒体服务器使用,功能十分强大. 官网下载地址:https://www.videolan.org/ VLC ...

  2. FFmpeg入门详解之116:rtsp live555摄像头直播

    rtsp+live555摄像头直播 Live555直播流程简介与演示 第一步,读取摄像头数据 第二步,x264编码 第三步,扩展live555 第四步,vlc或ffplay播放 ffplay -sta ...

  3. FFmpeg入门详解之83:流媒体与直播技术

    流媒体 流媒体又叫流式媒体,它是指商家用一个视频传送服务器(比如:vlc)把节目(比如:ande10.mp4)当成数据包发出,传送到网络上.用户通过解压设备对这些数据进行解压后,节目就会像发送前那样显 ...

  4. FFmpeg入门详解之117:视频监控的架构和流程

    几张架构图带您快速了解视频监控 图一 图二 图三 图四 视频监控系统的简介 视频监控 视频监控是安全防范系统的重要组成部分,英文Cameras and Surveillance.传统的监控系统包括前端 ...

  5. FFmpeg入门详解之121:颜色空间转换RGB和YUV的原理与实战

    5.颜色空间转换RGB和YUV的原理与实战 三种颜色空间模型:RGB.YUV.HSV 一.概述 颜色通常用三个独立的属性来描述,三个独立变量综合作用,自然就构成一个空间坐标,这就是颜色空间. 但被描述 ...

  6. FFmpeg入门详解之122:Qt5 FFmpeg本地摄像头采集预览实战

    6.Qt5+FFmpeg本地摄像头采集预览实战 源码工程:S26_Test2 FFmpeg命令行处理摄像头 ffmpeg -list_devices true -f dshow -i dummy 命令 ...

  7. FFmpeg入门详解之124:Qt5 FFmpeg单路网络摄像头采集预览

    Qt5+FFmpeg单路网络摄像头采集预览 源码工程:S26_Test4 RTSP协议简介 RTSP(Real Time Streaming Protocol),RFC2326 RTSP(Real T ...

  8. FFmpeg入门详解之111:RTSP协议2

    rtsp消息详解 1.RTSP的消息有两大类,一是请求消息(request),一是回应消息(response),两种消息的格式不同. 请求消息格式: 方法 URI RTSP版本 CR LF 消息头 C ...

  9. FFmpeg入门详解之119:FFmpeg的SDK编程回顾总结并操练

    3.FFmpeg的SDK编程回顾总结并操练 参考课程:"FFmpeg4.3--系列5--SDK二次开发详解与实战" FFmpeg主要框架 FFmpeg骨架:"八大金刚&q ...

最新文章

  1. 图解Transformer:Attention Is All You Need
  2. UrlDecode和base64
  3. 智慧办公的AI博弈——看飞企互联如何接招!
  4. Linux系统Logrotate服务介绍
  5. 火影忍者服务器维护时间,火影手游12月12日更新:仙鸣增加破霸体,小自来也变蛙时间减半!...
  6. Pandas系列(十五)stack和pivot实现数据透视
  7. [渝粤教育] 江苏农牧科技职业学院 兽医文化 参考 资料
  8. 三星手机如何分屏_艺术大片如何拍?快拜三星Galaxy S20 5G系列为师|三星|摄像头|手机|远景...
  9. 百战学堂python教学文档_尚学堂百战程序员:python对文件的操作
  10. STAP旁瓣干扰抑制与干扰对抗仿真
  11. 添加WhatsApp链接教程
  12. 石墨烯在生物医学上应用的研究进展_石墨烯在润滑油中的应用
  13. DELL服务器运行硬件检测
  14. 拿什么产品引流年轻女性?发什么能吸引女粉丝?
  15. B2C模式电商案例分享
  16. winusb —— 不再为你的usb设备编写驱动
  17. 后台管理系统中的登录页面
  18. iPad 使用技巧:备忘录
  19. shell win10 改成cmd_Win10 的 PowerShell、CMD 和 Windows Terminal 全方位美化配置方法
  20. HDU 6305 RMQ Similar Sequence(笛卡尔树)

热门文章

  1. 我,30多岁的土木工程人,终于转行了
  2. php 访问php_PHP的美味邪恶
  3. 分页查询_小记录(模糊查询点页数暂未完成,只能上下页)
  4. java幼儿园信息管理系统
  5. 2020-09-16莫安迪摄影作品-中山公园晚霞
  6. 信息系统集成管理【2016年五月错题】
  7. Docker中安装宝塔
  8. 信息学奥赛一本通:1308:【例1.5】高精除
  9. javascript实现卡片式效果
  10. ESB接口调用异常汇总