iOS 怎么使用ijkplayer

iOS 怎么使用ijkplayer,第1张

打开八门神器,最小化,打开你要改的游戏,最小化,打开八门神器有一个选择程序,选你要改的那个,然后输入你要改的金币或者属性,然后自动匹配,我举一个例子比如你玩神庙逃亡,右上角是你跑的米,你就要先跑一下,比如到了100米你就暂停,打开八门神器输入100,然后自动匹配,这时候会有很多个100出来,因为数据叫100的有很多,然后你直接最小化八门神器不要关,打开神庙逃亡继续,跑到了200,再在刚刚输数据那里输200,这时候数据就会少很多,在跑一次到300再输到八门神器基本上就剩一个数据了,然后点开那个数据随便改,返回游戏就看到你的数据变成了多少。八门神器就是要先找到哪个数据是你要改的就能随便改

音频变速播放原理分析及实现方案

[关键词:音频,audio,倍速,变速,变调,soundtouch,sonic]

音频变调变速原理分析

先来一段语音处理的理论:

语音变调在变声软件中较常用。而语音变速在播放器中常用,比如倍速播放(快播、慢播)。本文重点关注变速。

相对于视频基于帧的变速原理,跳帧或者插帧。音频的变速原理并不是如此简单,因为简单的抽采样点会引起声音的不连续、噪声或爆破音,主观体验较差。

所以一下简单的音频处理策略通常是行不通的:(以x2倍速为例)

1播放设备实现,设置播放设备播放采样率加倍,这样单位时间播放的采样点数加倍,可以实现变二倍速不变调,但声音不连续。

2播放前PCM重采样为原采样率的一半,可以实现二倍速,但是会变调。

3丢帧,每隔一帧丢一帧,可以实现两倍速,但是也会有刺啦刺啦的噪音,而且声音会产生断续,体验十分差。

可用方案

所以为了实现较好的主观体验,只能采用相对复杂的语音处理策略。目前较为常用的音频变速解决方案有两个:soundtouch和Sonic。

ijkplayer使用的是soundtouch,EXOPlayer使用的是Sonic。

在Android上还有一种实现方式,基于AudioTrack的变速播放,代码如下:

详细用法建议参考PlaybackParams。

Sonic和Soundtouch用法类似,都是提供封装好的库,将原音频的PCM数据通过接口函数处理为目标格式,比如二倍速,可能PCM采样点就减半。

这里以Soundtouch提供的接口为例,说明下如下使用:

参数设置类接口:

setChannels(int) 设置声道,1 = mono单声道, 2 = stereo立体声

setSampleRate(uint) 设置采样率

setRate(double) 指定播放速率,原始值为10,大快小慢

setTempo(double) 指定节拍,原始值为10,大快小慢

setRateChange(double)、setTempoChange(double) 在原速10基础上,按百分比做增量,取值(-50 +100 %)

setPitch(double) 指定音调值,原始值为10

setPitchOctaves(double) 在原音调基础上以八度音为单位进行调整,取值为[-100,+100]

setPitchSemiTones(int) 在原音调基础上以半音为单位进行调整,取值为[-12,+12]

PCM处理类接口:

putSamples(const SAMPLETYPE samples, uint nSamples) 输入采样数据

receiveSamples(SAMPLETYPE output, uint maxSamples) 输出处理后的数据,需要循环执行

flush() 冲出处理管道中的最后一组“残留”的数据,应在最后执行

从上述接口来看,类似于常规的解码器或者解复用器的调用逻辑。

小结

本文简述了音频变速变调的原理,并对目前Android平台上可用的音频变速方案做了总结,包括Soundtouch、Sonic及AudioTrack三种方案,仅供后续参考。

FFmpeg名称中的mpeg来自视频编码标准MPEG,而前缀FF是Fast Forward的首字母缩写。

目录

默认的编译会生成 4 个可执行文件和 8 个静态库。可执行文件包括用于 转码 、 推流 、Dump媒体文件的 ffmpeg 、用于播放媒体文件的 ffplay 、 用于获取媒体文件信息的 ffprobe ,以及作为简单流媒体服务器的 ffserver 。

8个静态库其实就是FFmpeg的8个模块,具体包括如下内容。

比如AAC编码,常见的有两种封装格式

AAC 的 bit stream filter 常常应用在 编码 的过程中。

与音频的AAC编码格式相对应的是视频中的 H264编码 ,它也有两种封装格式

FFmpeg中也提供了对应的 bit stream filter ,称 H264_mp4toannexb ,可以将MP4封装格式的H264数据包转换为annexb封装格式的H264数据 (其实就是裸的H264的数据)包。

H264 的 bit stream filter 常常应用于视频解码过程中。

ffmpeg 是进行媒体文件转码的命令行工具

ffprobe 是用于查看媒体 文件头信息的工具

ffplay 则是用于播放媒体文件的工具

1首先用ffprobe查看一个音频的文件

2输出格式信息format_name、时间长度duration、文件 大小size、比特率bit_rate、流的数目nb_streams等。

3以JSON格式的形式输出具体每一个流 最详细 的信息

4显示帧信息的命令如下:

5查看包信息的命令如下:

ffplay是以FFmpeg框架为基础,外加渲染音视频 的库libSDL来构建的媒体文件播放器。

业界内开源的 ijkPlayer 其实就是基于 ffplay 进行改造的播放器,当然其做了硬件解码以及很多兼容性的工作。

在 ffplay中音画同步的实现方式其实有三种。分别是

并且在 ffplay 中默认的对齐方式也是以 音频 为基准进行对齐的。

首先要声明的是,播放器接收到的视频帧或者音频帧,内部都会有 时间戳(PTS时钟) 来标识它实际应该在什么时刻进行展示。

实际的对齐策略如下:比较视频当前的播放时间和音频当前的播放时间

关键就在于音视频时间的比较以及延迟的计算,当然在比较的过程中会设 置一个 阈值(Threshold) ,若超过预设的阈值就应该做调整(丢帧渲染 或者重复渲染),这就是整个对齐策略。

ffmpeg 就是强大的媒体文件转换工具。它可以转换任何格式的媒体文件,并且还可以用自己的 AudioFilter 以及 VideoFilter 进行处理和编辑。

接下来介绍一个解码的实例,该实例实现的功能非常单一,就是把一个视频文件解码成单独的音频PCM文件和视频YUV文件。

AVFormatContext是API层直接接触到的结构体,它会进行格式的封 装与解封装。

该结构体包含的就是与实际的 编解码 有关的部分。

331 av_register_all

所以该函数的内部实现会先调用 avcodec_register_all 来注册所有configh里面开放的编解码器,然后会注册所有的 Muxer 和 Demuxer (也就是封装格式),最后注册所有的 Protocol (即协议层的东西)。

332 av_find_codec

这里面其实包含了两部分的内容:一部分是寻找 解码器 ,一部分是寻找 编码器 。

333 avcodec_open2

该函数是打开编解码器(Codec)的函数,无论是编码过程还是解码过程,都会用到该函数。

avformat_open_input

根据所提供的文件路径判断文件的格 式,其实就是通过这一步来决定使用的到底是哪一个 Demuxer 。

avformat_find_stream_info

方法的作用就是把所有 Stream 的 MetaData 信息填充好。

av_read_frame

使用该方法读取出来的数据是 AVPacket 。

对于 音频流 ,一个 AVPacket 可能包含 多 个 AVFrame ,但是对于 视频流 ,一个 AVPacket 只包含 一 个 AVFrame ,该函数最终只会返回一个 AVPacket 结构体。

avcodec_decode

该方法包含了两部分内容:一部分是 解码视频 ,一部分是 解码音频 , 解码 是会委托给对应的解码器来实施的。

avformat_close_input

该函数负责释放对应的资源。

avformat_alloc_output_context2

该函数内部需要调用方法avformat_alloc_context来分配一个 AVFormatContext 结构体。

avio_open2

编码的阶段了,开发者需要将手动封装好的 AVFrame 结构体,作为 avcodec_encode_video 方法的输入,将其编码成为 AVPacket ,然后调用 av_write_frame 方法输出到媒体文件中。

本文参考 音视频开发进阶指南

项目源码地址 - FFmpegDecoder

一.基本知识和通讯录中联系人相关的应用iPhone提供了两个框架:AddressBookframework和AddressBookUIframework,使用这两个框架我们可以在程序中访问并显示iPhone数据库中的联系人信息。二.具体介绍1AddressBookUI显示部分AddressBookUI中提供了和联系人显示信息相关的一些Controller,有四个:ABPeoplePickerNavigationController:显示整个通讯录并可以选择一个联系人的信息ABPersonViewController:显示一个具体联系人的信息ABNewPersonViewController:增加一个新的联系人ABUnknownPersonViewController:完善一个联系人的信息由于其中最主要的是ABPeoplePickerNavigationController,因此就具体的介绍一下通过程序显示整个通讯录并且可以选择其中某个联系人信息的步骤。(a)创建并初始化一个ABPeoplePickerNavigationController对象(b)设置其代理(delegate)(c)用presentModalViewController:animated:这个方法进行显示整个通讯录页面例子:复制代码-(IBAction)showPicker:(id)sender{ABPeoplePickerNavigationControllerpicker=[[ABPeoplePickerNavigationControlleralloc]init];pickerpeoplePickerDelegate=self;[selfpresentModalViewController:pickeranimated:YES];[pickerrelease];}复制代码ABPeoplePickerNavigationControllerDelegate的方法介绍(a)peoplePickerNavigationControllerDidCancel:当用户选择取消时调用这个方法,可以在这个方法里取消整个通讯录页面的显示。(b)peoplePickerNavigationController:shouldContinueAfterSelectingPerson:当用户选择了通讯录中某一个联系人时调用这个方法,可以在这里获取联系人的信息。如果希望可以继续显示这个联系人更具体的信息,则returnYES。否则取消整个通讯录页面的显示并returnNO。(c)peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier:如果上一个方法返回的是YES,则会显示某一个联系人信息,如果选择了联系人的某一项纪录,就会调用这个方法,可以通过点击选择联系人的某一项信息。如果希望可以对选择的某一项纪录进行进一步 *** 作,比如直接拨打电话或调用邮箱发送邮件,则returnYES。否则取消整个通讯录页面的显示并returnNO。例子:(a)示例:-(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController)peoplePicker{//assigningcontrolbacktothemaincontroller[pickerdismissModalViewControllerAnimated:YES];}(b)示例:复制代码-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController)peoplePickershouldContinueAfterSelectingPerson:(ABRecordRef)person{//获取联系人姓名nametext=(NSString)ABRecordCopyCompositeName(person);//获取联系人电话ABMutableMultiValueRefphoneMulti=ABRecordCopyValue(person,kABPersonPhoneProperty);NSMutableArrayphones=[[NSMutableArrayalloc]init];inti;for(i=0;i!$_"]){[phonesaddObject:aPhone];}}phoneNotext=@"";if([phonescount]>0){NSStringmobileNo=[phonesobjectAtIndex:0];phoneNotext=mobileNo;//NSLog(mobileNo);}//获取联系人邮箱ABMutableMultiValueRefemailMulti=ABRecordCopyValue(person,kABPersonEmailProperty);NSMutableArrayemails=[[NSMutableArrayalloc]init];for(i=0;i0){NSStringemailFirst=[emailsobjectAtIndex:0];emailtext=emailFirst;//NSLog(emailFirst);}[peoplePickerdismissModalViewControllerAnimated:YES];returnNO;}复制代码(c)示例-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController)peoplePickershouldContinueAfterSelectingPerson:(ABRecordRef)personproperty:(ABPropertyID)propertyidentifier:(ABMultiValueIdentifier)identifier{returnNO;}2AddressBook部分AddressBook框架部分主要是记录联系人的各个信息,ABRecordRef类型的记录既可以代表单个人(kABPersonType),也可以是一个集合(kABGroupType)。通讯录中联系人的各个属性有两种形式,单值属性和多值属性。单值属性对应的只有一个值,比如联系人的姓名;多值属性对应的可能有多个值,比如联系人有多个电话号码等。(a)常用方法CFTypeRefABRecordCopyValue(ABRecordRefrecord,ABPropertyIDproperty);从一个记录中获取某个属性对应的值(b)单值属性对应的方法CFStringRefABRecordCopyCompositeName(ABRecordRefrecord);获取联系人完整的姓名。(c)多值属性对应的方法CFTypeRefABMultiValueCopyValueAtIndex(ABMultiValueRefmultiValue,CFIndexindex);返回对应位置处的属性值CFStringRefABMultiValueCopyLabelAtIndex(ABMultiValueRefmultiValue,CFIndexindex);返回对应位置处的属性标识CFArrayRefABMultiValueCopyArrayOfAllValues(ABMultiValueRefmultiValue);返回包含所有属性值的数组CFIndexABMultiValueGetCount(ABMultiValueRefmultiValue);返回属性值的个数

以上就是关于iOS 怎么使用ijkplayer全部的内容,包括:iOS 怎么使用ijkplayer、为什么音频的bpm降低但是速度会变快、第三章 FFmpeg的介绍与使用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9501999.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存