java用来做音视频解析的还是挺少的,刚巧领导给分派了这个工作,就硬着头皮干了4个月。基本上算能解决mp4的音视频解析了。share一下,希望能对有这方面需求的人提供帮助,也希望能有更好的建议和解决方案。
此文不涉及RTP,RTCP协议,H264解码,因为本人的专业知识实在有限,不过我还是特别希望有此方面开发经验的兄弟指点一二(c/c++ 方向的也可以)
Lib:这里用到了jave(一个日本的framework封装了ffmpeg),spring2.5.6,依赖于jdk1.6和ffmpeg SDK3.2。
MP4利用ffmpeg分割为aac和h264文件分别解析,可将如下代码封装到java.lang.ProcessBuilder,多线程调用进行MP4分离。
ffmpeg.exe -i **.mp4 **.h264 -vstats_file **.log
ffmpeg.exe -i **.mp4 **.aac
特别说明下,分离**.h264文件后面跟了一个 -vstats_file **.log ,这是视频分隔输出流日志,后面解析h264文件时要用到的,目前这个日志只试用于win主机,*nix经测试打印日志不全,暂时没找到好的解决方法.
一 aac格式文件的解析:
aac文件格式很简单,header(7个字节)-content-header-content...,其中header分为fixed和variable两种,这里采用标准音频(援引标准文档):
adts_fixed_header()
{
syncword; 12 bslbf
ID; 1 bslbf
layer; 2 uimsbf
protection_absent; 1 bslbf
profile; 2 uimsbf
sampling_frequency_index; 4 uimsbf
private_bit; 1 bslbf
channel_configuration; 3 uimsbf
original/copy; 1 bslbf
home; 1 bslbf
}
adts_variable_header()
{
copyright_identification_bit; 1 bslbf
copyright_identification_start; 1 bslbf
frame_length; 13 bslbf
adts_buffer_fullness; 11 bslbf
number_of_raw_data_blocks_in_frame; 2 uimsfb
}
可以看到,两部分各28比特位,共56比特位,7字节.
首两个字节一般都是1111 1111 1111 0001,如果音频数据包含crc校验信息,最后一位就是0(看文档是这样的,但没有实作).
对应关系如下:
syncword 1111 1111 1111
ID 0
layer 00
protection_absent 1
然后接下来的一个半字节,
如下:
profile 两位,见下表
sampling_frequency_index 四位,见下表
private_bit 0
channel_configuration 三位,见下表,立体声为2,即010
original_copy 0
home 0
这部分标志位需要解释一下,援引标准文档
profile
Table 31 – Profiles
0 Main profile
1 Low Complexity profile (LC)
2 Scalable Sampling Rate profile (SSR)
3 (reserved)
再看Variable部分
前两位,一般都是00
copyright_identification_bit 0
copyright_identification_start 0
数值,等于数据包大小加上7--header的大小.其实就是第二个adts chunck的起始地址.
frame_length 00 0001 1000 000
全是1,即0x7FF
adts_buffer_fullness 1 1111 1111 11
一般为00
number_of_raw_data_blocks_in_frame 00
比特位映像:
1111
1111
1111
0 00 1
xx xx-
xx 0 x-
x x 0 0
0 0 xx-
xxxx
xxxx
xxx 1-
1111
1111-
11 00
这里附一些我解析aac文件的代码:
private long parse(long offset) throws CannotParseException {
int fl = 0;
try {
is.skip(offset);
byte[] syncword = new byte[2];
int i = is.read(syncword);
if (i != -1) {
if (syncword[0] == -1 && (syncword[1] & -15) == -15) {
is.skip(1);
byte[] framelength = new byte[3];
int k = is.read(framelength);
if (k != -1) {
byte front = (byte) (framelength[0] & 3);
byte middle = framelength[1];
byte end = (byte) (((framelength[2] & -32) >> 5) & 7);
fl |= front;
fl <<= 8;
fl |= middle;
fl <<= 3;
fl |= end;
AudioBean bean = new AudioBean();
bean.setFramenum(++blocks);
bean.setOffset(fl);
bean.setPosition(position);
list.add(bean);
position += fl;
} else {
return -1;
}
} else {
return -1;
}
} else {
logger.info("aac file that length's : " + position + " parse done!");
return 0;
}
} catch (IOException ex) {
logger.error("during parse aac file occur unexpected exception", ex);
throw new CannotParseException(ex);
}
return fl - 7 + 1;
}
递归上面这个方法,记录一些关键的字段,保存到list里,这里我定义了一个对象AudioBean,他继承于MediaBean,没有子类字段。因为标准aac文件时线性的,所以记录了以下字段,以便分析。
public class MediaBean implements Serializable {
/**
* 起始位置
*/
private long position;
/**
* 每帧偏移量
*/
private int offset;
/**
* 帧位置
*/
private int framenum;
/**
* 起始时间
*/
private float time;
//setter getter 方法
}
由于是标准线性aac,那么总时间与总帧数的比大概就是每帧的时间(必须注明下,没有decode aac文件的内部数据,需要精确数据的请不要采取此方法)。经过处理的list<MeadiaBean>是一个完成的aac信息,我们可以用他来处理aac文件的截取和传输。
二 H264文件的解析
刚才的命令行产生的**.log文件现在用到了。贴一小段log信息
frame= 1 q= 31.0 f_size= 6927 s_size= 7kB time= 0.083 br= 665.0kbits/s avg_br= 665.0kbits/s type= I
frame= 2 q= 31.0 f_size= 17 s_size= 7kB time= 0.167 br= 1.6kbits/s avg_br= 333.3kbits/s type= P
frame= 3 q= 31.0 f_size= 11 s_size= 7kB time= 0.250 br= 1.1kbits/s avg_br= 222.6kbits/s type= P
frame= 4 q= 31.0 f_size= 11 s_size= 7kB time= 0.333 br= 1.1kbits/s avg_br= 167.2kbits/s type= P
frame= 5 q= 31.0 f_size= 11 s_size= 7kB time= 0.417 br= 1.1kbits/s avg_br= 134.0kbits/s type= P
其中 frame 为帧数,f_size为此帧大小,s_size是一个不是特别精确的累积帧大小,time为结束时间。
这些字段已经足够分析h264文件了。
项目还包括缓存,池,等概念,是一个完成的视频发送服务器,涉及到公司内部的视频协议就不公开了。希望能结识有视频研发经验的朋友,交流经验,其实我想把他再完善一下做成一个开源的视频分析框架,无奈专业知识有限,尤其是aac和h264方面的。
分享到:
相关推荐
在Java编程环境中,音频解析是一项重要的任务,它涉及到读取、处理和理解音频文件的内部结构。本篇文章将深入探讨如何使用Java进行音频解析,并提供相关的代码示例。我们将主要关注以下几个方面:音频文件格式、Java...
Java音视频播放源码是一个基于Java编程语言实现的多媒体播放器项目,主要涵盖了音频和视频的播放功能。这个项目对于想要深入理解Java多媒体处理、音视频解码以及播放器开发的开发者来说,是一个很好的学习资源。下面...
Java语音视频功能是一种在Java平台上实现的多媒体技术,它涵盖了语音识别和语音写入的核心技术。这个项目提供了从音频输入捕获声音,并将其转化为可读的文本的能力,这对于开发交互式应用,例如智能助手、在线客服...
综上所述,音视频时长解析软件通过Java代码解析类对音视频文件进行读取和解析,以提取出文件的时长信息。这个过程涉及到对不同文件格式的理解,以及对二进制数据的处理能力。提供的代码示例是解析过程的一个简化版本...
### Android 音视频精编编码解析 #### 一、引言与背景介绍 随着移动互联网技术的迅猛发展,音视频应用已经成为人们日常生活中不可或缺的一部分。无论是视频通话、在线教育还是远程办公,高质量的音视频服务都是...
1. **视频解析**:FFmpeg的ffprobe工具可以用来解析视频文件的元数据,包括编码信息、帧率、分辨率、音频流等。在Java中,我们可以构建一个包含"ffprobe"命令和视频文件路径的字符串数组,然后使用ProcessBuilder...
这通常需要使用多媒体处理库,例如FFmpeg,它可以解析MP4文件的盒子结构,获取视频和音频的编码信息。 2. 对齐时间轴:由于视频和音频可能有不同的时间基准,需要确保两者在合并时同步。可能需要根据实际情况调整...
而Xuggler则是一个开源的Java库,它允许开发者操作音视频文件的元数据,进行剪辑、转码等操作。 在"java实现视频压缩"这个项目中,可能会包含以下步骤: 1. **读取视频文件**:使用Java的FileInputStream或相关的...
"解析TS流,播放音视频"这个主题涉及到多个关键技术点,包括TS流解析、网络传输(UDP组播)、音视频解码以及播放显示。我们将逐一探讨这些知识点。 首先,TS(Transport Stream)流是一种广泛用于数字电视和卫星...
在Java中实现视频播放,首先需要解析视频文件,获取其编码格式和帧数据。然后,通过RTPManager创建RTP会话,设置本地和远程的网络地址和端口,将视频帧封装到RTP包中,并通过UDP发送出去。在接收端,RTPManager接收...
"JT_1078音视频传输协议开发指南 - Hentai.org.cn.pdf"这份文档应该提供了详细的协议解析、实例演示以及开发过程中的注意事项,是学习和实施JT_1078协议的重要参考资料。通过深入学习,开发者可以更好地掌握协议的...
通过阅读和理解这些代码,开发者可以学习到如何在Java环境中进行H264到MP4的转换,这对于那些需要处理音视频流的项目非常有用。 在使用`h264ToMP4.jar`时,你可能需要提供输入的H264文件路径和期望的输出MP4文件...
Xuggler是一个强大的开源库,专为处理音视频数据而设计,它提供了丰富的API,使得在Java环境中解析和操作多媒体文件变得简单。在本文中,我们将详细探讨如何使用Xuggler来获取这些重要信息。 首先,Xuggler基于...
Xuggler是一个开源的Java库,它允许开发者读取、修改和写入多种多媒体容器格式(如MP4, FLV, AVI等)以及各种编码的音视频流。要使用Xuggler获取视频的分辨率和大小,你需要导入相关的类并创建一个IMediaReader对象...
Java实现的视频播放程序源码是一个典型的多媒体应用开发案例,主要涉及了Java编程语言、音视频处理技术以及软件工程的一些核心概念。以下是对这个项目的一些关键知识点的详细说明: 1. **Java编程语言**:Java是一...
本项目源码的主题是“使用Java进行视频解析”,这意味着我们将深入探讨如何利用Java处理多媒体数据,特别是视频文件。视频解析是将视频文件转换为可操作的数据,以便进行播放、编辑或进一步分析的过程。 在Java中,...
直播软件开发之Java音视频解决方案:音视频基础知识 直播软件开发之Java音视频解决方案,需要了解音视频基础知识。从信息论的角度来看,描述信源的数据是信息和数据冗余之和,即:数据=信息+数据冗余。音频信号在...
这些库提供了处理音视频数据的底层接口,包括读取、解析、编码和写入等操作。 2. **时间处理**:为了准确地截取指定时间段,我们需要理解视频的时间线,这通常涉及时间码(timestamp)的处理。时间码是表示视频帧相...
开发者可能使用这些API来解析不同的音频和视频格式,如MP3、AAC、MP4、AVI等,并将它们转化为可播放的流。 接着,**图形用户界面(GUI)**设计至关重要。JAVA提供了Swing和JavaFX这两个主要的GUI工具包,用于构建用户...
Java中的FFmpeg库被广泛用于处理音视频相关的任务,其中包括获取视频时长。FFmpeg是一个开源项目,提供了命令行工具和一系列的库,用于处理多媒体数据。在Java中使用FFmpeg,开发者可以方便地集成到自己的应用中,...