阿里媒体转码公共参数_Xuggler教程:转码和媒体修改

阿里媒体转码公共参数

注意:这是我们的“ Xuggler开发教程 ”系列的一部分。

在上一教程中,我对视频处理Xuggler进行了简短介绍 。 在这一部分中,我们将看到Xuggler和FFmpeg提供的一些更令人兴奋的功能,例如视频转码和媒体修改。 别忘了Xuggler是一个Java库,可用于实时解压缩,处理和压缩录制的视频或实时视频。

Xuggler提供了两种不同的编程API,可用于同一目的。 首先,我们有MediaTool API :

MediaTool是一个简单的应用程序编程接口(API),用于对Java中的视频进行解码,编码和修改。 MediaTool隐藏了许多容器,编解码器和其他细节的细节,因此您可以专注于媒体而不是工具。 也就是说,MediaTool仍然提供对底层Xuggler对象的访问,因此,如果需要,您可以进行精细的控制。

还有Xuggler Advanced API ,它使您可以深入研究视频操作的细节,但又增加了一层复杂性。

首先,我们将使用MediaTool API ,在随后的教程中,我们还将处理Advanced API。

让我们开始将媒体从一种格式转码为另一种格式。 代码转换是一种编码到另一种编码的直接数模转换。 通常在目标设备不支持该格式或存储容量有限(要求减小文件大小)或将不兼容或过时的数据转换为更好支持的格式或现代格式的情况下执行此操作。 转码通常是一个有损过程 ,其中“有损”压缩是一种数据编码方法,为了达到其目标,它会丢弃(丢失)一些数据,结果是,对数据进行解压缩会产生与原始数据不同的内容,尽管足够相似,以某种方式有用。

让我们看一些用于转码的高级代码,稍后我将详细解释。

package com.javacodegeeks.xuggler;import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaViewer;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;public class TranscodingExample {private static final String inputFilename = "c:/myvideo.mp4";private static final String outputFilename = "c:/myvideo.flv";public static void main(String[] args) {// create a media readerIMediaReader mediaReader = ToolFactory.makeReader(inputFilename);// create a media writerIMediaWriter mediaWriter = ToolFactory.makeWriter(outputFilename, mediaReader);// add a writer to the reader, to create the output filemediaReader.addListener(mediaWriter);// create a media viewer with stats enabledIMediaViewer mediaViewer = ToolFactory.makeViewer(true);// add a viewer to the reader, to see the decoded mediamediaReader.addListener(mediaViewer);// read and decode packets from the source file and// and dispatch decoded audio and video to the writerwhile (mediaReader.readPacket() == null) ;}}

只需几行代码,我们就可以将MPEG-4输入文件转换为FLV文件。 我们首先创建用于读取和解码媒体的IMediaReader 。 它打开一个媒体容器,从中读取数据包,解码数据,然后将有关数据的信息分发到任何已注册的IMediaListener对象。 这是IMediaWriter类起作用的地方。 它对媒体进行编码和解码,同时处理音频和视频流。 为了使事情变得更有趣,我们还将IMediaViewer附加到我们的阅读器上。 它用作调试工具,使我们可以在解码时观看视频。 此外,在此过程中,我们还会看到各种统计信息。 请注意,该类处于实验模式,这意味着它有一些可能会挂起的错误,因此请谨慎处理。

本质上,使用上面的代码,我们将两个侦听器IMediaWriter和IMediaViewer附加到IMediaReader对象,并在读取器读取和解码源文件中的数据包的同时处理回调。 这是在“ while”循环中执行的。 如果我们使用示例输入文件运行该应用程序,将显示类似于以下内容的屏幕:

该过程完成后(由于我们正在同时实时观看,因此该过程将与源视频文件一样长),将以FLV格式创建一个新的输出文件。

让我们从命令行使用Ffmpeg来比较输入和输出文件:

ffmpeg.exe -ic:/myvideo.mp4
似乎流1编解码器的帧速率与容器的帧速率不同:59.92(14981/250)-> 29.96(14981/500)
从'c:/myvideo.mp4'输入#0,mov,mp4,m4a,3gp,3g2,mj2:
元数据:
major_brand:mp42
minor_version:0
兼容品牌:isomavc1mp42
持续时间:00:04:20.96,开始:0.000000,比特率:582 kb / s
流#0.0(und):音频:aac,44100 Hz,立体声,s16、115 kb / s
流#0.1(und):视频:h264,yuv420p,480×270 [PAR 1:1 DAR 16:9],464 kb / s,29.96 fps,29.96 tbr,29962 tbn,59.92 tbc

在原始视频文件中,容器为MPEG-4 ,有两个流:使用44100Hz AAC的音频流和使用H.264的视频流。

ffmpeg.exe -ic:/myvideo.flv
似乎流0编解码器的帧速率与容器的帧速率不同:1000.00(1000/1)-> 29.97(30000/1001)
从'c:/myvideo.flv'输入#0 flv:
元数据:
持续时间:261
宽度:480
高度:270
videodatarate:62
帧率:30
videocodecid:2
音频数据率:62
音频采样率:44100
音频样本大小:16
立体声:真
音频编解码器:2
文件大小:43117478
持续时间:00:04:20.98,开始:0.000000,比特率:128 kb / s
流#0.0:视频:flv,yuv420p,480×270、64 kb / s,29.97 tbr,1k tbn,1k tbc
流#0.1:音频:mp3,44100 Hz,2声道,s16,64 kb / s

转码后,生成的Flash视频文件使用FLV视频流和MP3音频流。

现在,我们准备使用Xuggler修改媒体文件。 但是在编写代码之前,我们需要了解MediaTool的工作原理 :

MediaTool使用事件侦听器范例。 写入器会自动作为“侦听器”添加到读取器,并接收所有解码的媒体。 IMediaViewer和IMediaWriter接口(查看器和编写器实际上是什么)实现IMediaListener接口,并且可以作为侦听器添加到IMediaReader。

我们通过前面的示例确认了这一点。 事实是,为了对输入文件进行各种修改 ,我们必须设置“媒体管道”。 我们创建IMediaTool的自定义实现,然后以链式方式在每个工具上设置侦听器,以便它们将数据从一个传递到另一个。

假设我们希望在视频中添加静态图像,同时希望减少音频量。 在这种情况下,我们将创建两个自定义IMediaTool对象:

  • StaticImageMediaTool:拍摄视频图片并在屏幕上的特定位置标记静态图像文件。
  • VolumeAdjustMediaTool:按恒定因子调整音量。

另外,我们创建一个IMediaWriter对象,该对象将用于创建输出文件。 通过所有这些,我们创建了一条链,如下所示:

读取器-> addStaticImage-> reduceVolume->写入器

让我们看看实现以上所有功能的代码:

package com.javacodegeeks.xuggler;import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ShortBuffer;import javax.imageio.ImageIO;import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaTool;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IAudioSamplesEvent;
import com.xuggle.mediatool.event.IVideoPictureEvent;public class ModifyMediaExample {private static final String inputFilename = "c:/myvideo.mp4";private static final String outputFilename = "c:/myvideo.flv";private static final String imageFilename = "c:/jcg_logo_small.png";public static void main(String[] args) {// create a media readerIMediaReader mediaReader = ToolFactory.makeReader(inputFilename);// configure it to generate BufferImagesmediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);IMediaWriter mediaWriter = ToolFactory.makeWriter(outputFilename, mediaReader);IMediaTool imageMediaTool = new StaticImageMediaTool(imageFilename);IMediaTool audioVolumeMediaTool = new VolumeAdjustMediaTool(0.1);// create a tool chain:// reader -> addStaticImage -> reduceVolume -> writermediaReader.addListener(imageMediaTool);imageMediaTool.addListener(audioVolumeMediaTool);audioVolumeMediaTool.addListener(mediaWriter);while (mediaReader.readPacket() == null) ;}private static class StaticImageMediaTool extends MediaToolAdapter {private BufferedImage logoImage;public StaticImageMediaTool(String imageFile) {try {logoImage = ImageIO.read(new File(imageFile));} catch (IOException e) {e.printStackTrace();throw new RuntimeException("Could not open file");}}@Overridepublic void onVideoPicture(IVideoPictureEvent event) {BufferedImage image = event.getImage();// get the graphics for the imageGraphics2D g = image.createGraphics();Rectangle2D bounds = new Rectangle2D.Float(0, 0, logoImage.getWidth(), logoImage.getHeight());// compute the amount to inset the time stamp and // translate the image to that positiondouble inset = bounds.getHeight();g.translate(inset, event.getImage().getHeight() - inset);g.setColor(Color.WHITE);g.fill(bounds);g.setColor(Color.BLACK);g.drawImage(logoImage, 0, 0, null);// call parent which will pass the video onto next tool in chainsuper.onVideoPicture(event);}}private static class VolumeAdjustMediaTool extends MediaToolAdapter {// the amount to adjust the volume byprivate double mVolume;public VolumeAdjustMediaTool(double volume) {mVolume = volume;}@Overridepublic void onAudioSamples(IAudioSamplesEvent event) {// get the raw audio bytes and adjust it's valueShortBuffer buffer = event.getAudioSamples().getByteBuffer().asShortBuffer();for (int i = 0; i < buffer.limit(); ++i) {buffer.put(i, (short) (buffer.get(i) * mVolume));}// call parent which will pass the audio onto next tool in chainsuper.onAudioSamples(event);}}}

与往常一样,我们首先创建一个IMediaReader并在调用IMediaListener.onVideoPicture时使用setBufferedImageTypeToGenerate方法生成BufferedImage图像。 为了将我们的自定义图像覆盖在实际的视频图片上,这是必要的。 然后,我们创建IMediaWriter和媒体工具对象,并如上所述配置工具链。 让我们仔细看看自定义媒体工具。

首先,我们有StaticImageMediaTool类。 它扩展了MediaToolAdapter并覆盖了onVideoPicture方法,因为我们希望以此来操纵视频流。 在构造函数中,我们已经使用ImageIO.read方法加载了一个图像文件。 JavaCodeGeeks徽标用于此目的(实际上是其缩小版本)。 然后,在已实现的onVideoPicture方法中,我们通过调用IVideoPictureEvent.getImage获得基础的BufferedImage并创建Graphics2D对象。 然后,我们使用Graphics.drawImage方法覆盖静态图像。 最后,我们调用父onVideoPicture方法,该方法会将视频传递到链中的下一个工具。

然后,我们有了VolumeAdjustMediaTool。 它还扩展了MediaToolAdapter ,但覆盖了onAudioSamples方法,该方法在对音频样本进行解码或编码后调用。 在那里,我们通过调用IAudioSamplesEvent.getAudioSamples来获取原始音频字节,并使用相应的ShortBuffer类调整其值。 再次,在自定义处理之后,我们调用父onAudioSamples方法,该方法会将音频传递到链中的下一个工具。 如果现在运行此应用程序,我们将在原始视频的顶部看到添加的图像,并且音频音量将大大降低。
而已。 Xuggler支持的转码和媒体处理。 与往常一样,您可以下载为本教程创建的Eclipse项目 。 请继续关注JavaCodeGeeks上的更多Xuggler教程! 别忘了分享!

相关文章:

  • Xuggler视频处理简介
  • Xuggler教程:帧捕获和视频创建
  • 使用wowza和xuggler将RTMP转为RTSP

翻译自: https://www.javacodegeeks.com/2011/02/xuggler-tutorial-transcoding-media.html

阿里媒体转码公共参数

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

52单片机iic读写c语言,如何52单片机的I2C读写24C08程序问题排查修改

------波形在一楼isoimg2130老师提供在单片机正常运行的程序&#xff1a;#include "reg52.h"#include "intrins.h"typedef unsigned char u8;sbit SCLP2^1; //I2C 时钟sbit SDAP2^2; …

怎么用c语言写一个贪吃蛇,刚学C语言,想写一个贪吃蛇的代码

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include#include#include#includetypedef struct snake{int a;int b;struct snake *u;struct snake *n;}snake,*snake1;typedef struct food{int a;int b;}food;void main(){char c,c0 d;int i,j,k,n1,t,at;snake p,q;snake *dd,…

题目1065:输出梯形 (直接用循环控制输出)+题目1432:叠筐 (数组控制形状,最后输出数组)...

题目1065&#xff1a;输出梯形 &#xff08;直接用循环控制输出&#xff09; 样例输入&#xff1a; 4 样例输出&#xff1a; ****************** ********** 题目1432&#xff1a;叠筐 样例输入&#xff1a; …

毕业设计C语言网吧管理系统,毕业设计网吧管理系统.doc

毕业设计网吧管理系统.doc本科生毕业论文(设计)题目&#xff1a; 网吧管理系统――服务器子系统学 院 数学与计算机学院学科门类 理 科专 业 信息与计算科学学 号 024092553姓 名 陈绍指导教师 白云2007年5月25日网吧管理系统——服务器子系统摘 要随着上个世纪九十年代计算机网…

sql注入查找注入点_基本的EJB参考,注入和查找

sql注入查找注入点在本系列的第一部分中 &#xff0c;我们介绍了Enterprise JavaBeans v。3.0规范提供的机制&#xff0c;用于定义EJB组件&#xff0c;声明对EJB的引用并通过依赖项注入或程序化JNDI查找将它们连接起来。 在此博客文章中&#xff0c;我们将研究一些基本示例以了…

安徽省c语言选择题题库,C语言选择题题库.doc

C语言程序设计题库说明一 本题库适用对象计算机应用技术计算机软件软件技术计算机网络技术与计算机控制技术等专业二 本题库包含有175道选择题三 本题库所有题目均附有答案一、选择题下列各题ABCD四个选项中&#xff0c;只有一个选项是正确的&#xff0c;请将正确选项涂在答题卡…

求二叉树的最小深度

思路&#xff1a;用递归的方法求解。 输入&#xff1a;二叉树的根节点&#xff1b; 输出&#xff1a;二叉树的最小深度。 最小深度的定义&#xff1a;从根节点到叶子节点的最短路径上的节点数。 算法如下&#xff1a; 将二叉树分为这么几种情况&#xff1a; 传入的根节点为空&a…

qfp封装能够linux,QFP、PQFP、LQFP、TQFP封装形式及PCB详解

问题&#xff1a;画PCB时&#xff0c;会发现很多的集成电路都是QFP封装&#xff0c;比如很多的单片机都有这种封装。各个器件商会在自己的数据手册中说明他的器件是QFP&#xff0c;LQFP或TQFP&#xff0c;然后&#xff0c;有的给出封装尺寸图&#xff0c;有的则不给。那么&…

编写下载服务器。 第三部分:标头:内容长度和范围

这次&#xff0c;我们将探索更多的HTTP请求和响应标头&#xff0c;以改善下载服务器的实现&#xff1a; Content-length和Range 。 前者表示下载量很大&#xff0c;后者允许部分下载文件或在我们开始时失败后继续下载。 Content-length响应标头对于跟踪下载进度的客户端非常有…

dede文章列表加上序号效果

dede文章列表加上序号效果 css代码部分 <style type"text/css"> <!-- .downtop { FLOAT: left; OVERFLOW: hidden; WIDTH: 218px; HEIGHT: 278px } .downtop UL.text { MARGIN: 0px 10px; WIDTH: 198px; PADDING-TOP: 5px } .downtop UL.text LI { WIDTH: 1…

解答互联网创业中,你肯定会遇到的问题!

作为创过业&#xff0c;并且失败了的人&#xff0c;还是有那么一点点经验来回答这些问题的。1.我现在有个idea&#xff0c;上线之前如何在保证不被泄露的情况下又能了解这个idea对用户有多大吸引力&#xff1f;答&#xff1a;短时间内快速做出原型&#xff0c;找到10个左右的目…

android 垂直自动滚动条,Android实现Activity水平和垂直滚动条的方法

本文实例讲述了Android实现Activity水平和垂直滚动条的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;android:layout_width"match_parent"android:layout_height"match_parent"android:scrollbars"vertical" >android:layout_…

javadoc定义异常_Doclava:来自Google的自定义Javadoc Doclet

javadoc定义异常Doclava是Google的自定义Javadoc Doclet&#xff0c;由Google Guice使用&#xff08;请参见稍冷一些的Javadocs &#xff09;。 Doclava使用JSilver作为其模板引擎&#xff0c;这是Clearsilver的纯Java实现。 我个人喜欢联合文档的想法&#xff0c;该概念允许文…

HDU 2845 Beans

本来是很简单的一道题&#xff0c;却想了好长时间 由于数据量比较大&#xff0c;所以逐行读入&#xff0c;逐行处理 先处理每一行的不相邻元素和的最大值&#xff0c;记录在数组b中 最后计算不相邻行的和的最大值 二者的状态转移方程都类似&#xff1a;dp[j] max(dp[j - 1], d…

计算机由什么组成

对于一个不是计算机专业的编程人员&#xff0c;有很多东西要去学习&#xff0c;一直不理解计算机的组成和原理&#xff0c;今天查看百科&#xff0c;稍微了解一下写出来&#xff0c;让以后巩固&#xff1a; 1&#xff0c;计算机是由硬件系统和软件系统组成的 硬件系统&#xff…

android 重新启动应用程序,通过单击应用程序图标打开Android应用程序时重新启动...

我是Android开发世界的新手,我已经建立了一个简单的“Hello World”应用程序.首先,活动请求一个文本.当单击“Go”按钮时,应用程序将启动显示输入文本的第二个活动.如果我单击HOME按钮,然后单击应用程序图标,该应用程序将再次启动第一个活动,但是如果我按住主屏幕按钮并单击“最…

继承,is,as,多态

继承中的构造方法&#xff1a;1、创建子类对象时&#xff0c;一定会先创建父类对象2、如果调用的子类构造方法没有使用base&#xff0c;就会自动调用父类无参的构造方法&#xff0c; 如果父类没有无参的构造方法就会报错3、如果调用的子类构造方法使用了base&#xff0c;就会…

太古鸿蒙诀正式版v1.07,百变队长安崎:台上小辣椒,台下情歌王

在舞台上魅力四射的THE9队长安崎&#xff0c;在台下却是喜欢唱情歌的软萌girl。这样的安崎你爱了么&#xff1f;反差萌王者安崎作为队长&#xff0c;在舞台上的表现一直都是“炸裂”、“辣”、“性感”、“野性”&#xff0c;而舞台之下的安崎则一直呈现的是可爱、甜美&#xf…

erlang 架构原理_Erlang与Java内存架构

erlang 架构原理我读了一篇关于Erlang VM的内存管理策略的非常非常有趣的文章。 它是Jesper Wilhelmsson撰写的论文 &#xff0c;我认为讨论Erlang的内存设置和Oracle的Java VM之间的差异可能会很好。 作为对从未听说过Erlang的人们的一个简短的介绍; 它是一种功能语言&#xf…

ASP.NET MVC IOC 之AutoFac攻略

一、为什么使用AutoFac&#xff1f; 之前介绍了Unity和Ninject两个IOC容器&#xff0c;但是发现园子里用AutoFac的貌似更为普遍&#xff0c;于是捯饬了两天&#xff0c;发现这个东东确实是个高大上的IOC容器~ Autofac是.NET领域最为流行的IOC框架之一&#xff0c;传说是速度最快…