0%

Base of Multimedia——Sound

wjlkoorey

声音一个最基本的常识就是“它是一种能量”,初中物理课上我们也学过声音的三要素分别是音色、音调和响度。
音色:简单理解,就是一种声音的固有特征。比如,电子琴和小提琴发出的声音是有明显区别的,笛子和古筝也有各自的声音特征。有些声音模仿秀的选手可以通过训练,达到模仿不同人或者不同乐器的效果。
音调:也就是我们所说的频率,单位是赫兹Hz,频率越高听起来越刺耳、越尖锐,频率越低听起来越低沉、越浑厚。医学研究表明,人的听觉系统能察觉的最低频率为20Hz,最高为20000Hz,超出这个范围人类一般就听不到了。其实现实生活中根本就不存在完全能听到20Hz~20kHz这样的人,并且随着年龄的增长、体质的变化,人能听到的声音只会是这个区间的一个子集。

人对不同频率、不同分贝的声音的生理反应也是有差别的,正如我们中医里提到的“五音”(角、徵、宫、商、羽)和身体脏腑(心、肝、脾、肺、肾)以及对人心神(喜、怒、忧、思、悲)的影响是一样的。

例如“宫”调,风格悠扬沉静、淳厚庄重,根据五音通五脏的理论,宫调入脾,对消化系统的作用比较明显。这就是为什么很多古代电视或者电影里,皇庭寿宴席的时候一般都是奏宫乐。如果对中华文化感兴趣的朋友肯定注意到,我们古代繁体字的药材的“藥”和音乐的“樂”的字根是一样的,可见老祖宗造字时并不是瞎画的,这说明声音的确还是可以治病。现在精通音律的老师傅是越来越少了。感慨一句,中华文明,博大精深,后继者何也?呜呼。。。扯远了,收一下。

而人一般能发出的声音频率也是男女有别,大致范围如下:

低音
中音
高音

82 Hz~392Hz
123 Hz~493Hz
164 Hz~698Hz

220 Hz~1.1kHz

响度:就是声音的大小,一般用“分贝”来表示,单位是dB,这个参数说明了声音所携带的能量的大小,声音越大,在相同传播介质里所能传递的距离就远。

在物理世界里,我们的声音在传输过程中都是连续,像下面这个样子:

可是如果要让计算机来处理它,就牵扯到我们经常说的数字化了。关于声音在数字化过程中有三个核心步骤:采样、量化和编码。

采样:在模拟声音的时间轴上周期性地取点,将时域连续的模拟信号变成离散信号的过程就叫做采样。每秒钟的采样点越多,数字化之后的声音就越接近原模拟声音。每秒钟的采样次数就叫做采样频率,根据奈奎斯特定律,采样频率fs和被采样声音的最高频率fmax的关系如下:

fs≥2fmax

PS:有些地方把声音的频谱范围也叫做声音的带宽,指的是声音从最低频率到最高频率之间的宽度。

量化:用于表示在采样点所获取的声音能量值。量化就是将空域连续的模拟信号转换成离散信号的过程。量化精度越高,所能表示的声音采样范围就越大,量化误差就也越小,相应地,所占用的存储空间也就越大。简而言之,就是对于采样所得到的样本点,我们打算用几位二进制数来表示它。例如,如果是8bit的量化精度,那么我们最多能表示的采样点就只有256个;如果是16bit,最多能表示的采样点就可以多达65536个。

编码:对于经过采样量化后的数据按一定的算法进行编码处理。在计算机里最接近模拟声音的编码方式就是PCM脉冲编码方式。那么对于上述量化结果,我们发现这段音频采样点的量化空间最多也就是11个,我们用4bit就可以完全表示它们了。所以量化精度就是4bit,可表示的样本空间是[0~15],因此,上述编码序列就是{3,5,6,7,8,5,4,8,10,8,5,1,1,2,5}。

当然,真正到了量化阶段时又分均匀量化和非均匀量化,量化的同时就自动编码成PCM格式的数据了。通常意义来说,量化和编码都是同时进行的。

ITU-T建议的G.711是最早公布的语音编码标准,它规定了A律13折线和u律15折线PCM编码的两种方案。这里就不再继续展开了,都是数学层面的东东,不纠结。中国和欧洲采用的A律13折线的PCM编码方式,北美和日本采用的是u律15折线的PCM编码方式。

在计算机里我们就认为PCM就是数字音频信号的原始无损格式,其存储方式通常是.wav文件,即wav格式的音频文件就是原始的未经任何压缩处理的数字音频文件,这样的文件大部分情况下都来自于录音设备。如果你使用音频格式转换工具将mp3转成wav的话,那么很不幸的是你的这个wav并不是无损格式的文件,因为mp3格式的文件是对原始wav文件经过有损压缩后得来的,而这个过程不是可逆的,即mp3转成的wav只有原始wav的部分信息。但从人的听觉系统来说,一般人是分辨不出来其中的差别,除非用专业发烧级音响设备,再加上一双有着专业特性的耳朵,区别还是很明显的。

例如,我们手头现在有款奥林巴斯的LS-14专业数码录音笔,我们将采样频率设为44100Hz,量化精度为16bit,采用双声道的模式进行音频录制,每秒钟所产生的数据量为44100x16x2=176400 bit,那么3分钟将会产生的声音数据约为30.28MB。显然,这个结果显然不太令人满意,接下来就有了各种音频压缩算法的出现,也就是多媒体技术术语里所说的编码器,其实就是压缩算法而已。目的只有一个:在高保真原有音质的前提下,最大限度地对数字化之后的PCM编码文件进行压缩,以降低其所占的磁盘空间。整个过程可以描述如下:

幸运的是,现在PCM编码方式已经固化在很多音频设备的DSP芯片里了,不需要我们关心。一种编码算法一定对应一种相应的解码算法才行,不然编来有毛用。我们可以看到,整个过程中PCM编码格式充当了各种编解码器之间转换的中间桥梁,这也就是为什么我们说PCM格式的声音文是计算机里的“模拟文件”的原因了。不管是不同音频压缩格式之间的互相转换,还是最终输送给数模转换器的格式都是PCM格式。

上面几种格式里有个flac和其他几种格式有着本质的区别,flac是无损压缩格式,和它齐名还有家喻户晓的ape格式。什么意思?无损格式的音频文件是在对原始wav文件压缩是没有删减过滤它的任何信息的情况下,完全通过算法活生生的把wav文件的体重给减了下来,而且flac和ape可以完整还原原始wav的所有信息,一个毫毛都不差。ape的压缩比高达55%。这和那些有损压缩的mp3、ogg、aac等是没法相比的,因为人家是无损的,就这么简单。有些人喜欢听CD,而另外一些人则喜欢听mp3,其实他们根本就不是一个级别的,也没有可比性的。最后,献上天王的一首单曲以飨各位看官肯花宝贵的时间听我在这里唧唧歪歪的大半天,配上森海或者AKG的耳机好好享受一下生活吧(不敢保证每个人能都听到那种感觉,毕竟人家mp3也不是盖的)。

人生不止眼前的代码和BUG,还有耳朵与音乐。

附件:Billie.Jean-apeBillie.Jean-mp3

多媒体技术基础之—Come on!来点儿音乐吧

其实要说在Linux系统下播放音乐,确实是一件让人非常抓狂的事情,抛开各种音频格式的商业授权不说,即使提供给你相应的解码库,能玩儿得转的人那又是少之又少。可能有些盆友说ubuntu这方面确实做得不错,一旦默认安装好,几乎不用装任何其他东西,常见的是音频文件都可以正常播放了。因为我天生就有股喜欢折腾的劲儿,所以关于ubuntu确实不怎么感冒,只能说萝卜白菜各有所爱吧。今天我们以wav文件(也就是上一篇博文所提到的PCM格式的音频文件)为例,看看在Linux下怎么播放它,顺便会简单介绍一下Linux系统的音频驱动框架的基础知识。
说到Linux系统下的音频系统驱动框架,最常见的有OSS和ALSA。我们先来简单了解一下这两个框架,以及它们的历史渊源。
OSS全称是Open Sound System,叫做开放式音频系统,最早是Unix系统上一种统一的音频接口。这种基于文件系统的统一访问方式,就意味着对声音的操作完全可以像对普通文件那样执行open,read,write和close等操作,这也正是得益于文件系统的强大有力支撑。OSS中,主要提供了一下几种音频设备的抽象设备文件:
/dev/mixer:用来访问声卡中内置的混音器mixer,用于调整音量大小和选择音源;
/dev/dsp、/dev/audio:读这个设备就相当于录音,写这个设备就相当于放音。/dev/dsp与/dev/audio的主要区别在于所采样的PCM编码方式的不同,/dev/audio使用的是μ律编码(存在这个设备文件的目的主要是为了与SunOS兼容,所以在非SunOS系统中尽量不要使用),而/dev/dsp使用8-bit(无符号)的线性编码;
/dev/sequencer、/dev/sequencer2:主要用于访问声卡内置的,或者连接在MIDI接口的合成器synthesizer。
还有其他的诸如/dev/adsp、/dev/dmmidi、/dev/midi等等,一些不常用的就先不管了。看一下我的CentOS 5.3内核版本2.6.21系统中的音频设备文件:

我们可以直接使用Unix/Linux的命令来放音和录音,例如,命令cat /dev/dsp >xyz 可用来录音,录音的结果放在xyz文件中;命令cat xyz >/dev/dsp播放声音文件xyz。当然,我们还可以通过open、close、read、write、ioctl等这些文件的操作函数直接控制这些设备,达到对声音应用程序级别的访问与控制。那么这么看来OSS应该还算比较完美了,Linux下的声音编程应该没有难度才对,怎么会说Linux下声音变成是一件很头疼的事儿呢?
其实OSS自从诞生到OSSv3版及其之前,都是Linux的原始声音系统,并集成在内核代码里。当OSS被4Front Technologies收购后,于2002年OSSv4作为商业软件的出现时,它的命运就被我们接下来要介绍的ALSA给改写了。其实严格意义上来说,商业化不是导致OSS没落的根本原因,也有技术层面的因素在,比如OSS的混音功能。由于先天的设计缺陷,OSS对混音的支持非常糟糕,由于当时的声卡本身是支持多路输出的混合,所以OSS就偷懒了,将混音的任务交给了声卡,所以那个年代的程序猿们为了操作混音器,代码里充斥着大量的ioctl函数,现在看起来相当难受。
ALSA全称是Advanced Linux Sound Architecture,叫做Linux系统下的高级音频架构,它主要为声卡提供的驱动组件,以替代原先的 OSS。这个项目最早始于1998年Gravis Ultrasound所开发的驱动,它一直作为一个单独的软件包开发,直到2002年他被引进入Linux内核的开发版本(2.5.4-2.5.5)。自从2.6版本开始ALSA成为Linux内核中默认的标准音频驱动程序集,而OSS则被标记为废弃。所以,现在看来OSS被ALSA替代,闭源和商业化都只是外因,内因还是其设计的缺陷。虽然2007年4Front又宣布OSSv4重新在GPL协议下重新开源,但已经人去楼空秋已暮了,现在ALSA对OSS的支持也比较好了,不知道OSS还能否王者归来。其实这些都不重要,对于开发者来说,简单、便捷、高效、实用才是王道,优美的框架结构,完善的文档支持强过口水战百倍。
目前ALSA已经成为Linux系统里主流的音频系统框架,在2.6.21的内核里已经看不到OSS的影子了。在内核设备驱动层面,ALSA提供了alsa-driver,同时在应用层,ALSA也为我们提供了alsa-lib,应用程序只要调用alsa-lib所提供的API,就可以完成对底层音频硬件的控制:

上图向我们展示了ALSA的一个简单的结构,用户空间的alsa-lib对应用程序提供统一的API接口,这样可以隐藏了驱动层的实现细节,简化了应用程序的实现难度。内核空间中,alsa-soc其实是对alsa-driver的进一步封装,针对嵌入式设备提供了一些列增强的功能,通常也被叫做ASoC,即Alsa-soc的缩写,像Android系统中底层就用了ASoC。想了解ALSA更多细节的盆友可以访问他们的官网:http://www.alsa-project.org/main/index.php/Main_Page

下面,我们首先看一下OSS下如何播放wav文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
点击(此处)折叠或打开
/*playsound.c*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/soundcard.h>

#define AUDIO_DEVICE "/dev/dsp"

int play_sound(char *filename,int rate,int bits){
struct stat stat_buf;
unsigned char *buf = NULL;
int result,arg,status,handler,fd;

fd = open(filename,O_RDONLY);
if(fd<0)
return -1;

if(fstat(fd,&stat_buf))
{
close(fd);
return -1;
}

if(!stat_buf.st_size)
{
close(fd);
return -1;
}

buf=malloc(stat_buf.st_size);
if(!buf){
close(fd);
return -1;
}

if(read(fd,buf,stat_buf.st_size)<0){
free(buf);
close(fd);
return -1;
}

handler = open(AUDIO_DEVICE,O_WRONLY);
if(-1 == handler){
return -1;
}

arg = rate*2;
status = ioctl(handler,SOUND_PCM_WRITE_RATE,&arg);
if(-1 == status)
return -1;

arg = bits;
status = ioctl(handler,SOUND_PCM_WRITE_BITS,&arg);
if(-1 == status)
return -1;

result = write(handler,buf,stat_buf.st_size);
if(-1 == result)
return -1;

free(buf);
close(fd);
close(handler);
return result;

}

int main(int argc,char** argv){
play_sound(argv[1],atoi(argv[2]),atoi(argv[3]));
return 0;
}

因为只是演示用,所以错误判断就少了一些。另外,为了让我们的播放程序自动获得音频文件的参数,诸如采样率,量化精度等,我又提供了一个shell脚本player:
点击(此处)折叠或打开

#!/bin/sh
[ “$#” -eq 0 ] && {
echo “Usage: $0 filename”
exit
}
BITS=file $1 | cut -d' ' -f9
RATE=file $1 | cut -d' ' -f12

echo “Playing…$(file $1)”
./playsound $1 $RATE $BITS
将上述C文件编译,然后,在命令行之./player 文件名,不出意外的话就可以听到声音了,只可惜没办法演示这个过程:

我的系统确实可以听到,但是声音比较小,如果你在命令行执行amixer的话,应该可以看到下面的输出信息:

我的声卡音量居然只有75%(因为我用的虚拟机),然后一句“amixer set Master 100%”命令下去,再重新播放声音,应该就很happy了。

其实大家可能有点疑惑,不是前面介绍了半天ALSA的好处了,怎么用OSS来示范,是不是专拣软柿子捏啊。再说了,现在很多人的系统几乎都不支持OSS了,上面的代码有毛用。其实我也很不甘心,所以又重新装了CentOS6.3的虚拟系统,用ALSA的API再来播一下wav看得行不,经过N个小时的折腾,皇天不负有心人—It’s OK!(新手入门,大家来找BUG吧 :) )
内核版本2.6.32,看一下/dev目录下确实没有dsp和mixer设备文件了,取而代之的/dev/snd目录。在centos5.3里我们也见到过这个目录,但当时还只是试用阶段,现在alsa已经完全扶正了:

播放代码如下:
点击(此处)折叠或打开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/soundcard.h>
#include <alsa/asoundlib.h>

#define ALSA_MAX_BUF_SIZE 65535

int play_sound(char* filename,int rate,int bits,int channel,int order)
{
long loops;
int rc,size,dir;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
snd_pcm_uframes_t frames,periodsize;
snd_mixer_t *mixer;
snd_mixer_elem_t *pcm_element;

char *buffer;
unsigned int val;
FILE *fp = fopen(filename,"rb");
rc = snd_pcm_open(&handle,"default",SND_PCM_STREAM_PLAYBACK,0);

snd_pcm_hw_params_alloca(&params);
snd_pcm_hw_params_any(handle,params);
snd_pcm_hw_params_set_access(handle,params,SND_PCM_ACCESS_RW_INTERLEAVED);
switch(order){
case 1:
snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE);
break;
case 2:
snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE);
break;
defualt:
break;
}
snd_pcm_hw_params_set_channels(handle,params,channel);

val = rate;
snd_pcm_hw_params_set_rate_near(handle,params,&val,0);
snd_pcm_hw_params_get_buffer_size_max(params,&frames);
frames = frames < ALSA_MAX_BUF_SIZE? frames:ALSA_MAX_BUF_SIZE;
rc = snd_pcm_hw_params_set_buffer_size_near(handle,params,&frames);
snd_pcm_hw_params_get_period_size_min(params,&periodsize,NULL);
if(!periodsize){
periodsize=size/4;
}
rc = snd_pcm_hw_params_set_period_size_near(handle,params,&periodsize,NULL);
rc = snd_pcm_hw_params(handle,params);

snd_mixer_open(&mixer,0);
snd_mixer_attach(mixer,"default");
snd_mixer_selem_register(mixer,NULL,NULL);
snd_mixer_load(mixer);
for(pcm_element = snd_mixer_first_elem(mixer);pcm_element;pcm_element=snd_mixer_elem_next(pcm_element))
{
if(snd_mixer_elem_get_type(pcm_element)==SND_MIXER_ELEM_SIMPLE && snd_mixer_selem_is_active(pcm_element))
{
if(!strcmp(snd_mixer_selem_get_name(pcm_element),"Master"))
{
snd_mixer_selem_set_playback_volume_range(pcm_element,0,100);
snd_mixer_selem_set_playback_volume_all(pcm_element,(long)100);
}
}
}

buffer = (char*)malloc(size);
while(1)
{
rc = fread(buffer,1,size,fp);
if(0== rc)
break;
while((rc = snd_pcm_writei(handle,buffer,size))<0)
{
usleep(200);
if(-EPIPE == rc)
snd_pcm_prepare(handle);
else if(0 > rc)
printf("error fomr writei\n");
}
}
snd_pcm_drain(handle);
snd_pcm_close(handle);
free(buffer);
snd_mixer_close(mixer);
fclose(fp);
return 0;
}


int main(int argc,char** argv){
play_sound(argv[1],atoi(argv[2]),atoi(argv[3]),atoi(argv[4]),atoi(argv[5]));
return 0;
}
然后将player脚本也对应修改一下:
点击(此处)折叠或打开
#!/bin/sh
[ "$#" -eq 0 ] && {
echo "Usage: $0 filename"
exit
}
ORDER=`file $1 | cut -d' ' -f3`
BITS=`file $1 | cut -d' ' -f9`
CHANNEL=`file $1 | cut -d' ' -f11`
RATE=`file $1 | cut -d' ' -f12`
#channel
if [ "$CHANNEL" == "stereo" ]; then
CHANNEL=2
else
CHANNEL=1
fi
#platform-byte-order
if [ "$ORDER" == "(little-endian)" ]; then
ORDER=1
else
ORDER=2
fi
echo "Playing...$(file $1)"
./playsound $1 $RATE $BITS $CHANNEL $ORDER

编译C文件时,由于我们用了alsa库,所以gcc的编译选项要加上-lasound才可以。如果播放时声音很小,可以用amixer来调节音量。如果不幸的是你系统里找不到amixer命令的话,就用yum install alsa-utils或者下载alsa源码来安装吧。

附件是测试用的音频文件,另外,后面我会将完整支持OSS和ALSA两种架构的最终播放代码放在github上,有需要的盆友到时候可以拿去鼓捣鼓捣,今天就先到这里吧。

附件:news.wav

CentOS6.4完全安装FFmpeg手记

鼓捣媒体的人对FFmpeg应该不会陌生,它不仅功能强大,结构优美,灵活、易扩展,也是很其他多媒体播放器的基础,例如VLC,Mplayer等等,还有好多商业播放器都用了ffmpeg,但这些商业软件却没有遵守GPL公约,所以它们都被钉在了ffmpeg官网的“耻辱柱”上。关于ffmpeg还有一点题外话,那就是有一个叫做libav的开源项目。libav是从ffmpeg分化出来的一个项目,而这个项目诞生的原因和技术本身并没有任何关系,最大的分歧在于ffmpeg内部有一帮人对于ffmpeg项目的管理方式觉得不happy了,所以他们就自立门户,成立了libav这个项目。有意思的是libav官网的logo和ffmpeg官网的logo有点“小过节”,libav把ffmpeg官网那个偏着脑袋的logo给端正了,至于他们想传达的意义我觉得每个人都应该有自己的理解和认识。好了,开场预热就到这里,该干活了。
CentOS6.4的内核版本2.6.32-358,GCC版本是4.4.7,安装ffmpeg的版本是1.2,ffmpeg官网最新的版本是2.1,看着版本号差异挺大,其实从1.2到2.1中间仅隔了一个2.0版,是2013年7月10号刚发布。
安装前的准备工作当然是先安装各种工具:

点击(此处)折叠或打开
[root@localhost src]# pwd
/usr/local/src
[root@localhost src]# yum install automake autoconf make gcc gcc-c++ libtool zlib zlib-devel curl curl-devel alsa-lib alsa-lib-devel gettext gettext-devel expat expat-devel
ffmpeg作为一个多媒体框架和平台,最大的优势就在于可以很灵活地支持多种编解码和其他特性,只要第三方外部库支撑都可以做到。本次安装下列第三包依赖包:
faac:全称是Free Advanced Audio Coder,是MPEG-4和MPEG-2 AAC的一款常用的开源编解码器;
lame:一款常见的mp3的开源编解码器;
libass:先说一下ASS/SSA,其全称是Advanced Substation Alpha/Substation Alpha,是一种功能极为强大的字幕格式,主要用在视频文件里显示字幕。而libASS是一个轻量级的对ASS/SSA格式字幕进行渲染的函数库,使用C编写,效率非常高;
libdc1394:这是面向高级语言编程接口的一个库,主要提供了对符合IEEE 1394规范的数码摄录设备的一组操作接口。符合1395规范的数码相机标准的全称是1394-based Digital Camera Specifications,简称为IIDC或DCAM。安装dc1394需要先安装raw1394;
libfreetype2:freetype是一个用C语言实现的一个字体光栅化库,它可以用来将字符栅格化并映射成位图以及提供其他字体相关业务的支持。freetype提供了一个简单、易用并统一的接口来访问字体文件的内容。freetype不仅被自由桌面系统软件所使用,同时它也是现代视频游戏广泛使用的栅格化引擎;
libvorbis:这个库主要用于处理ogg格式的音频文件,而ogg全称是ogg vorbis,一种类似mp3的音频压缩格式。不同于mp3的是ogg完全免费、开放和没有专利限制的。ogg文件格式可以不断地进行大小和音质的改良,而不影响旧有的编码器或播放器,主要由Xiph.org基金会开发;
libtheora:theora也是Xiph.org基金会开发,是一种有损的影像压缩格式;
openssl:这个就不多说了,很多安全框架的基础;
rtmpdump:一个开源的rtmp格式的流媒体库,RTMP(Real Time Messaging Protocol)是Adobe Systems公司为它自家的flash播放器和服务器之间音频、视频和数据传输开发的一种开放的传输协议;
speex:speex是一套主要针对语音的开源免费、无专利保护的音频压缩格式,致力于通过提供一个可以替代高性能语音编解码来降低语音应用输入门槛。相对于其它编解码器,speex非常适合网络应用,因为它专为2-44kpbs语音码流所设计,所以在网络应用上有着自己独特的优势;
twolame:一个开源的mp2格式的编解码库;
vo-aacenc:AAC格式的常用的音频编码器;
xvidcore:是一个开放源代码的MPEG-4视频编解码器;
x264:目前最流行,最常见的H.264视频格式的一个开源的编解码器;

将需要的软件包全部下载后,剩下的事儿就非常简单:“三大步”—configure && make && make install
安装顺序如下:faac、lame、libtheora(需要先安装libogg)、libvorbis、vo-aacenc、xvidcore、x264、libdc1394(需要先安装libraw1394)、libass(需要先依次安装libfreetype2、fribidi和fonconfig)、openssl、librtmp、libspeex、twolame、yasm,最后安装ffmpeg。

在通过源码包安装上述软件时,如果在configure阶段没有用–prefix指定安装目录,默认情况下安装的顶级目录是/usr/local,可执行程序会被安装到/usr/local/bin,动态库被安装到/usr/local/lib,头文件在/usr/local/include等等。这样会有一个小小的麻烦,例如当先安装libogg后,再安装libtheora时,你有可能会收到如下的错误提示信息:
checking pkg-config is at least version 0.9.0… yes
checking for OGG… no
checking for Ogg… no
Could not run Ogg test program, checking why… The test program compiled, but did not run. This usually means
that the run-time linker is not finding Ogg or finding the wrong version of Ogg. If it is not finding Ogg, you’ll need to set your
LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point to the installed location Also, make sure you have run ldconfig if that
*** is required on your system


If you have an old version installed, it is best to remove it, although you may also be able to get things to work by modifying LD_LIBRARY_PATH
configure: error:
libogg is required to build this package!
please see http://www.xiph.org/ for how to
obtain a copy.

明明安装了ogg但theora却认为咱们没安装。原因在哪里,当然是动态库的查找路径了,想了解详情的童鞋请移步这里。我的解决办法是在 /etc/ld.so.conf.d/目录下创建一个名为local-libraries.conf的文件,内容很简单,只有一行:

点击(此处)折叠或打开
[root@localhost src]# cat /etc/ld.so.conf.d/local-libraries.conf
/usr/local/lib
[root@localhost src]#

然后执行ldconfig -v,然后再安装libtheora就很happy了。
当然还没完,当你在安装libass时,当你把所有依赖包都先安装之后,在configure阶段,它总会提醒你说:
Package requirements (freetype2 >= 9.10.3) were not met

任凭你怎么执行ldconfig都没用。不过你要是注意到错误提示信息其实问题的解决也就挺简单,在configure阶段在探测依赖包时用到了一个叫做pkg-config的工具,它会自动去查找当前系统是否支持某些类型的动态库文件,主要是通过一个.pc文件。而一些标准so库源码包里都会提供一个这样的文件以便pkg-config来用,而问题就在pkg-config查找.pc文件的路径上。关于这个工具更多细节就不展开了,感兴趣的朋友可以去google一下。这里我的解决办法是:

点击(此处)折叠或打开
[root@localhost libass-0.10.1]# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
然后安装libass时也就很happy了。
最后,在安装ffmpeg前需要先安装yasm,版本至少1.2.0以上。

下面是我的安装ffmpeg时相关软件包的配置情况,以便各位参考:

1 faac
[root@localhost faac]#./bootstrap
[root@localhost faac]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost faac]#make && make install

2 lame
[root@localhost lame-3.98.4]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost lame-3.98.4]#make && make install

3 libogg
[root@localhost libogg-1.3.0]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost libogg-1.3.0]#make && make install

4 libtheora
[root@localhost libtheora-1.1.1]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost libtheora-1.1.1]#ldconfig -v
[root@localhost libtheora-1.1.1]#make && make install

5 libvorbis
[root@localhost libvorbis-1.3.3]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost libvorbis-1.3.3]#make && make install

6 vo-aacenc
[root@localhost vo-aacenc-0.1.2]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost vo-aacenc-0.1.2]#make && make install

7 xvidcore
[root@localhost xvidcore-1.3.2]#./configure –prefix=/usr/local/
[root@localhost xvidcore-1.3.2]#make && make install

8 yasm
[root@localhost yasm-1.2.0]#./configure –prefix=/usr/local/
[root@localhost yasm-1.2.0]#make && make install

9 x264
[root@localhost x264-snapshot-20130505-2245]#./configure –prefix=/usr/local/ –enable-shared –enable-pic
[root@localhost x264-snapshot-20130505-2245]#make && make install

10 libraw1394
[root@localhost libraw1394-2.0.5]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost libraw1394-2.0.5]#make && make install

11 libdc1394
[root@localhost libdc1394-2.2.1]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost libdc1394-2.2.1]#make && make install

12 libfreetype
[root@localhost libfreetype2-master]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost libfreetype2-master]#make && make install

13 fribidi
[root@localhost fribidi-0.19.4]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost fribidi-0.19.4]#make && make install

14 fonconfig
[root@localhost fontconfig-2.9.0]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost fontconfig-2.9.0]#make && make install

15 libass
[root@localhost libass-0.10.1]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost libass-0.10.1]#make && make install (xuyao )

16 openssl
[root@localhost openssl-1.0.1c]#./config –prefix=/usr/local/ –openssldir=/usr/local/openssl threads zlib-dynamic shared
[root@localhost openssl-1.0.1c]#make && make install

17 librtmp
[root@localhost rtmpdump-2.3]#make SYS=posix
[root@localhost rtmpdump-2.3]#make install

18 libspeex
[root@localhost speex-1.2rc1]#./configure –prefix=/usr/local/ –enable-shared –enable-sse
[root@localhost speex-1.2rc1]#make && make install

19 twolame
[root@localhost twolame-0.3.13]#./configure –prefix=/usr/local/ –enable-shared
[root@localhost twolame-0.3.13]#make && make install

20 FFmpeg
[root@localhost ffmpeg-1.2]#./configure –prefix=/usr/local/ –enable-gpl –enable-version3 –enable-nonfree –enable-shared –enable-zlib –enable-bzlib –enable-libfaac –enable-libmp3lame –enable-libtheora –enable-libvo-aacenc –enable-libvorbis –enable-libx264 –enable-libxvid –enable-pic –enable-pthreads –enable-libdc1394 –enable-libass –enable-pic –enable-openssl –enable-libtwolame –enable-libspeex –enable-librtmp –enable-libfreetype
[root@localhost ffmpeg-1.2]#make && make install

安装完成后,测试一下:


为了方便各位测试,本文中用到的所有软件包已经放在网盘里,有需要的朋友请到这里下载。

欢迎关注我的其它发布渠道