观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

前言

  在摸索一段时间的音视频开发后,越来越发现这个坑的深度真是特别的深. 除了了解Android自带的音视频处理API以外,还得了解一些视频与音频方面的知识.这篇博客就是主要讲解这方面的专业术语.内容较多,如果你需要进行音视频开发是必需静下心来了解这些.

术语目录

  •   MIME类型
  •   分辨率
  •   sample-rate采样率
  •   bitrate比特率
  •   frame-rate帧速率
  •   capture-rate捕获率
  •   Data Rate码率
  •   视频编码格式/解码格式
  •   音频编码格式/解码格式
  •   YUV

MIME类型

  MIME是什么?截取一段百度百科的解释,偷偷懒...

 

  MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义文件名,以及一些媒体文件打开方式。
  它是一个互联网标准,扩展了电子邮件标准,使其能够支持:
  非ASCII字符文本;非文本格式附件(二进制、声音、图像等);由多部分(multiple parts)组成的消息体;包含非ASCII字符的头信息(Header information)。
这个标准被定义在RFC 2045、RFC 2046、RFC 2047、RFC 2048、RFC 2049等RFC中。 MIME改善了由RFC 822转变而来的RFC 2822,这些旧标准规定电子邮件标准并不允许在邮件消息中使用7位ASCII字符集以外的字符。正因如此,一些非英语字符消息和二进制文件,图像,声音等非文字消息原本都不能在电子邮件中传输(MIME可以)。MIME规定了用于表示各种各样的数据类型的符号化方法。 此外,在万维网中使用的HTTP协议中也使用了MIME的框架,标准被扩展为互联网媒体类型。
  
  所以..还是没太明白? MIME就是其实就是一个文件的类型标注,当然你可能更熟悉文件名的后缀.但是,文件中的MIME会在文件创建或者编码的时候添加到文件头里.所以,不会被轻易的改动.一般你右击文件的属性就可以查看到文件类型,如下图:
  
  图1.在这个文件的类型:我们可以看到video/mp4
  
  图2.在这个文件里,我们可以看到类型image/jpeg
  
  
 

MIME类型跟音视频开发有什么关联?

  有些小伙伴在了解过MIME下一个疑问肯定是这个.

  首先在Android开发中我们可以通过MediaExtractor方法获取到多媒体文件MIME的类型.其中的各种 video/avc  video/mp4v-es 格式是我们在开发音视频中一直需要时刻关注的东西.如果你的项目对视频格式要求严格,那么就需要在这方面做很多文章.

  其次重点!视频文件,其实是图像文件与音频文件合并的一个文件.所以它会包含2个甚至多个MIME类型.图像一个类型音频一个类型,如果多声道可能还会有多个音频.这时候你就明白了MIME的主要作用,就是在视频文件多个管道里找到图像类型的管道,将图像的流与音频剥离开.这样你就可以获得纯图像的流了. 看如下代码,获取一个视频里的MIME类型:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_extractor);
        mFile = new File(getExternalCacheDir(),"demo.mp4");
        mediaExtractor();
    }

    private void mediaExtractor(){
        try {
            MediaExtractor extractor = new MediaExtractor();
            extractor.setDataSource(mFile.getAbsolutePath());
            for (int i = 0; i < extractor.getTrackCount(); i++){
                MediaFormat mediaFormat = extractor.getTrackFormat(i);//获取多媒体格式
                String mimeFormat = mediaFormat.getString(MediaFormat.KEY_MIME);//获取MIME格式内容
                Log.e(TAG, "mediaExtractor: mimeFormat="+mimeFormat);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

最终结果:

2019-07-19 21:12:14.021 13202-13202/demo.yt.com.demo E/测试Demo: mediaExtractor: mimeFormat=video/mp4v-es
2019-07-19 21:12:14.023 13202-13202/demo.yt.com.demo E/测试Demo: mediaExtractor: mimeFormat=audio/3gpp

我们可以看到这个叫demo.mp4的文件,包含了2个通道,分别是视频的MP4与音频的3gpp

分辨率

  分辨率则是单位英寸中所包含的像素点数,分辨率也是视频的尺寸(宽高).分辨率越高视频就越清晰,并且视频尺寸就会越大.

  以上是很简单的描述,但是也足够描述清楚分辨率的知识了,但是肯定有很多人会有一些误区,下面我们来一一解答你可能理解错误的误区.

为什么我分辨率高了,视频还是不清晰? ---设备屏幕原因

   视频的分辨率高的确是视频是否清晰的重要标准,但是别忘记了你的播放设备屏幕是否支持这么高的分辨率?否则就是视频分辨率再高屏幕不支持,你依然无法看到高清视频.

为什么我分辨率高了,视频还是不清晰? ---比特率原因

  视频是否清晰,可不是只有分辨率一个属性决定的,其中也包括比特率.当然比特率将在下面讲解.比特率低你的分辨率再高也没有用.

明明我的视频是低分辨率,但是播放起来尺寸还是很大! 有一些高分辨率的视频为什么播放起来这么小啊?

  尺寸问题.我在上面说到分辨率等于视频的尺寸, 但是所有的播放器(包括你以后可能自己写的视频播放器),都需要重新适配视频的播放大小.你想想你拿一个1920*1080的视频到一个1280*720的设备上播放,屏幕怎么可能放的下你的视频.所以需要改变你的视频播放尺寸,按照比例改变了播放大小尺寸不等于压缩了视频分辨率.另外这里引入2个分辨率概念的理解分别是:

  1.屏幕分辨率

    设备的屏幕的尺寸与屏幕的分辨率无关,这里拿苹果手机举例子.以前的iPhone4的手机屏幕很小,但是又是十分清晰.原因是,在一英寸下iPhone4手机的屏幕塞入了更多更小的像素点.就可以让画面更加的清晰,但是尺寸依然还是这么小.

  2.视频分辨率

    视频的分辨率就是等于视频的尺寸大小,如果你要看到一个视频的真实尺寸,你只能找到一个对应宽高尺寸的设备来播放.否则,你看到的永远是播放器处理按比例缩小过的视频.

在音视频开发上,我应该注意分辨率的那些东西?

  在音视频开发上,对分辨率的处理永远是比例适配的难题.因为,我们的手机设备屏幕就这么大,不可能完整显示视频.所以需要调整我们播放视频View的大小,而View的大小是需要按照分辨率的比例进行缩小或者放大的.不按照比例缩小放大,那么你播放的视频肯定就会出现拉伸或者变形的情况.(关于比例适配的粗浅算法,在我的博客音视频开发分类里有介绍)

  其次,如果你想要压缩视频,对按比例缩小分辨率是一个错误的方向,因为分辨率的缩小是最毫无保留的压缩视频的方法.压缩后的视频在播放的时候会需要让视频放大,但是放大后的视频会显得更加模糊.所以,个人认为视频最好别修改分辨率来压缩视频. 因为还有其他更好的选择.

sample-rate采样率

  连续信号在时间(或空间)上以某种方式变化着,而采样过程则是在时间(或空间)上,以T为单位间隔来测量连续信号的值。T称为采样间隔。在实际中,如果信号是时间的函数,通常他们的采样间隔都很小,一般在毫秒、微秒的量级。采样过程产生一系列的数字,称为样本。样本代表了原来的信号。每一个样本都对应着测量这一样本的特定时间点,而采样间隔的倒数,1/T即为采样频率,fs,其单位为样本/秒,即赫兹(hertz)。

  通俗的讲采样频率是指计算机每秒钟采集多少个信号样本,比如声音信号,此时采样频率可以是描述声音文件的音质、音调,衡量声卡、声音文件的质量标准。采样频率越高,即采样的间隔时间越短,则在单位时间内计算机得到的样本数据就越多,对信号波形的表示也越精确。采样频率与原始信号频率之间有一定的关系,根据奈奎斯特理论,只有采样频率高于原始信号最高频率的两倍时,才能把数字信号表示的信号还原成为原来信号。在数字音频领域.

   采样率类似于动态影像的帧数,比如电影的采样率是24赫兹,PAL制式的采样率是25赫兹,NTSC制式的采样率是30赫兹。当我们把采样到的一个个静止画面再以采样率同样的速度回放时,看到的就是连续的画面。同样的道理,把以44.1kHZ采样率记录的CD以同样的速率播放时,就能听到连续的声音。显然,这个采样率越高,听到的声音和看到的图像就越连贯。当然,人的听觉和视觉器官能分辨的采样率是有限的,基本上高于44.1kHZ采样的声音,绝大部分人已经觉察不到其中的分别了。

  而声音的位数就相当于画面的颜色数,表示每个取样的数据量,当然数据量越大,回放的声音越准确,不至于把开水壶的叫声和火车的鸣笛混淆。同样的道理,对于画面来说就是更清晰和准确,不至于把血和西红柿酱混淆。不过受人的器官的机能限制,16位的声音和24位的画面基本已经是普通人类的极限了,更高位数就只能靠仪器才能分辨出来了。比如电话就是3kHZ取样的7位声音,而CD是44.1kHZ取样的16位声音,所以CD就比电话更清楚。

   

bitrate比特率

  比特率是指每秒传送的比特(bit)数。单位为 bps(Bit Per Second),比特率越高,传送的数据越大,音质越好.比特率 =采样率 x 采用位数 x声道数.

  关于比特率(比特率在音频或者视频领域也称为码率)的计算,比如,采样率为44.1KHz,以16bit采样,声道数为2,那么它的音频比特率的计算为:44100*16*2 = 1411200 bps = 1378 kbps,然后我们在除以8,将bit转化为Byte,所以1秒钟的数据量就是:1411200/8 = 176400 个字节(B)。

  另外,比特率是我们音视频开发的重要处理对象.比特率的大小关系着文件的大小,当我们需要压缩一个视频文件的时候,首先考虑的就是降低比特率.

比特率降低会出现什么效果?

   降低比特率,会让视频丢失一些像素点的值,而这个时候这个丢失值的像素点会去周围的的像素点上取到相识颜色的值.在一个较高的比特率下,如果我们一步步的压缩比特率就观察到画面的一些变化之处.

  首先,降低一些比特率可能会导致视频的锐度上升(锐度越高画面线条和边界越明显).在播放视频的时候因为视频已经丢失了一些像素点,而一些黑色线条上的灰色部分颜色值丢失后就会向周围的像素点取值,这个时候会取到黑色的值.就出现画面中黑色线条更加明显锐度上升的情况.

  然后,我们继续降低更多比特率,继续降低比特率会导致丢失的颜色值的像素点更多,这个时候视频的线条与边界反而会开始模糊,锐度瞬间下降.因为线条的像素点已经开始丢失颜色值了,在播放视频的时候他们会向周围的色块取中间值,这个时候你会发现线条模糊,画面模糊.

  在继续,降低更更更更多的比特率,哎,视频已经丢失了大块大块的像素点颜色值,在播放视频的时候某些残留的像素点将会成为他们的取值对象.这个取值是动态的会取到中间的随机颜色值.如果,你降低到这个份上,你的视频就已经基本上是马赛克的效果了...

反向操作提高比特率会出现什么效果?

  视频文件会增大,因为比特率增加,导致需多像素点上都会有颜色值.但是!并不会让更加视频清晰,反而有可能会让视频更模糊.因为,你并没有告诉那些像素点他们应该取什么值保存到文件里.所以,没有颜色值的像素点会向周围随便取值.但是这个取值后,是会保存到文件里的,所以你会感觉到文件增大.但是视频更加模糊.....

比特率的取值范围:

音频

  • 32 kbps —MW(AM) 质量
  • 96 kbps —FM质量
  • 128 - 160 kbps –相当好的质量,有时有明显差别
  • 192 kbps — 优良质量,偶尔有差别
  • 224 - 320 kbps — 高质量
  • 800 bps – 能够分辨的语音所需最低码率(需使用专用的FS-1015语音编解码器)
  • 8 kbps —电话质量(使用语音编码)
  • 8-500 kbps --Ogg Vorbis和MPEG1 Player1/2/3中使用的有损音频模式
  • 500 kbps–1.4 Mbps —44.1KHz的无损音频,解码器为FLAC Audio,WavPackMonkey's Audio
  • 1411.2 - 2822.4 Kbps —脉冲编码调制(PCM)声音格式CD光碟数字音频
  • 5644.8 kbps —SACD使用的Direct Stream Digital格式

视频

  • 16 kbps —可视电话质量(使用者可以接受的"说话的头"照片的最低要求)
  • 128 – 384 kbps — 商业导向的视频会议系统质量
  • 1 Mbps —VHS质量
  • 1.25 Mbps–VCD质量(使用MPEG1压缩)
  • 5 Mbps —DVD质量(使用MPEG2压缩)
  • 8 – 15 Mbps —高清晰度电视(HDTV) 质量(使用H.264压缩)
  • 29.4 Mbps –HD DVD质量
  • 40 Mbps – 蓝光光碟(Blu-ray Disc) 质量(使用MPEG2、H.264或VC-1压缩)
  • 440/880 Mbps – SonyHDCAM SR质量(SQ/HQ)

 

  上面是百度百科上提供的取值参考,是不是还是有一些概念模糊? 对音频的比特率来说,你可以按照上面的值换算成比特值使用.但是对视频却不一定是这样的固定的取值.上面的视频取值只是参考,假如你在准备调用相机拍摄视频,那么怎么才能设置一个合适当前分辨率比特率呢? (注意 ! 我这里说是拍摄视频的时候,因为已经拍摄完成的视频对比特率只有降低处理,提高毫无意义)

  首先你要记住一个公式:  N * width * height

  解释一下上面的公式,比如我们是一个 1920*1080 的分辨率的视频,这个就是通常的超清视频1080P的分辨率.那么这么一个分辨率的视频如何达到超清的要求呢. 一般是 5 * 1920 * 1080 = 10368000 这个值的比特率.如果你要更清晰可以继续调整N值,但是一般调整到10就是顶点了.(注意! 比特率不是无效大的,这关系到你的设备处理能力和设备的摄像头), 所以,一般情况下取值范围就是如下:

  • 1 * width * height -到- 10 * width * height

 

frame-rate帧速率

  帧速率是指每秒钟刷新的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。对影片内容而言,帧速率指每秒所显示的静止帧格数。要生成平滑连贯的动画效果,帧速率一般不小于8;而电影的帧速率为24fps。捕捉动态视频内容时,此数字愈高愈好。

  另外,我们降低帧率,也可以降低视频文件的大小.所以,在压缩视频的时候也可以考虑降低帧率,但是,过低帧率的下会导致视频卡顿不流程.所以,在帧率上可以调整的空间并不多....

帧率的取值范围

  一般是8 - 60的取值范围,在60以后在提高意义不大,因为人眼并办法在这么高的帧率下感觉到区别. 而我们拍摄视频一般取值 30 帧率即可.这是一个十分平衡文件大小与视频流畅度的取值.

 

Data Rate码率

  码率是与比特率一样的东西,虽然我对它只有初步的了解,但是个人认为码率其实就是比特率...只是叫法不同.

 

视频编码格式/解码格式

  所谓视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式视频流传输中最为重要的编解码标准有国际电联的H.261、H.263、H.264,运动静止图像专家组的M-JPEG国际标准化组织运动图像专家组的MPEG系列标准,此外在互联网上被广泛应用的还有Real-Networks的RealVideo、微软公司的WMV以及Apple公司的QuickTime等。

   视频最重要的部分就是编解码,一个视频在拍摄后保存成文件需要编码,而播放时则需要解码.而编解码最重要的就是编码格式. 目前最通用最好的视频编码格式是: H.264 / AVC. 所以,如果你不了解这些不要紧,直接选择这个就没错.

以下是Android里一般支持的几种视频编码格式.在google源码MediaRecorder.java 可以看到:

public static final int H263 = 1;
public static final int H264 = 2;
public static final int MPEG_4_SP = 3;
public static final int VP8 = 4;
public static final int HEVC = 5;

音频编码格式/解码格式

  从信息论的观点来看,描述信源的数据是信息和数据冗余之和,即:数据=信息+数据冗余。音频信号在时域和频域上具有相关性,也即存在数据冗余。将音频作为一个信源,音频编码的实质是减少音频中的冗余。这是一段百度百科的描述,每次其实所谓的音频编码就是压缩格式,将大量数据压缩成更小的数据,将重复冗余的信息去除.

  音频最重要的部分也是编解码,原理跟视频编解码一样.目前配合视频使用最通用最好的音频编码格式是: AAC ,单纯是音频的文件最好的编码格式是:AMR_NB

 以下是Android里一般支持的几种音频编码格式.在google源码MediaRecorder.java 可以看到:

/** AMR (Narrowband) audio codec */
public static final int AMR_NB = 1;
/** AMR (Wideband) audio codec */
public static final int AMR_WB = 2;
/** AAC Low Complexity (AAC-LC) audio codec */
public static final int AAC = 3;
/** High Efficiency AAC (HE-AAC) audio codec */
public static final int HE_AAC = 4;
/** Enhanced Low Delay AAC (AAC-ELD) audio codec */
public static final int AAC_ELD = 5;
/** Ogg Vorbis audio codec */
public static final int VORBIS = 6;

YUV

YUV 是一种彩色编码系统,主要用在视频、图形处理流水线中(pipeline)。相对于 RGB 颜色空间,设计 YUV 的目的就是为了编码、传输的方便,减少带宽占用和信息出错。

人眼的视觉特点是对亮度更铭感,对位置、色彩相对来说不铭感。在视频编码系统中为了降低带宽,可以保存更多的亮度信息(luma),保存较少的色差信息(chroma)。

Y’UV、YUV、YCbCr、YPbPr 几个概念其实是一回事儿。由于历史关系,Y’UV、YUV 主要是用在彩色电视中,用于模拟信号表示。YCbCr 是用在数字视频、图像的压缩和传输,如 MPEG、JPEG。今天大家所讲的 YUV 其实就是指 YCbCr。Y 表示亮度(luma),CbCr 表示色度(chroma)。

luminance 亮度,luma 是在视频编码系统中指亮度值;chrominance 色度,chroma 是在视频编码系统中指色度值。

Y’UV 设计的初衷是为了使彩色电视能够兼容黑白电视。对于黑白电视信号,没有色度信息也就是(UV),那么在彩色电视显示的时候指显示亮度信息。

Y’UV 不是 Absolute Color Space,只是一种 RGB 的信息编码,实际的显示还是通过 RGB 来显示。Y’,U,V 叫做不同的 component 。

YUV图解

YUV格式有两大类:planar和packed。
对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
对于packed的YUV格式,每个像素点的Y,U,V是连续交*存储的。

YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

    与我们熟知的RGB类似,YUV也是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。

YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0,关于其详细原理,可以通过网上其它文章了解,这里我想强调的是如何根据其采样格式来从码流中还原每个像素点的YUV值,因为只有正确地还原了每个像素点的YUV值,才能通过YUV与RGB的转换公式提取出每个像素点的RGB值,然后显示出来。

    用三个图来直观地表示采集的方式吧,以黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量。

先记住下面这段话,以后提取每个像素的YUV分量会用到。

  1. YUV 4:4:4采样,每一个Y对应一组UV分量。
  2. YUV 4:2:2采样,每两个Y共用一组UV分量。 
  3. YUV 4:2:0采样,每四个Y共用一组UV分量。

 

 

END

 

posted on 2019-07-19 21:15  观心静  阅读(1463)  评论(0编辑  收藏  举报