当前位置: 首页 > 编程日记 > 正文

iOS音频——AudioToolbox

一、前言
二、音频文件Audio File Services
三、音频文件转换Extended Audio File Services
四、音频流Audio File Stream Services
五、音频队列Audio Queue Services

一、前言

AudioToolbox提供的API主要是C 使用起来相对晦涩,针对本文提供了简单的代码示例减小学习的阻力 AudioToolbox


AudioToolbox

采样和采样率

sample 是一个声道的一个采样。采样率定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。


image.png


frame 是最小单位时间点包含的一个或多个声音采样,最小单位时间点取决于声音采样设备,是一个时间点多个采样的集合。譬如,双声道的音频文件,一个时间点有两个声道,一个Frames就包括两个采样。通道是声音的通道的数目。常有单声道和立体声之分。


image.png


采样位数即采样值或取样值(就是将采样样本幅度量化)。它是用来衡量声音波动变化的一个参数,也可以说是声卡的分辨率。它的数值越大,分辨率也就越高,所发出声音的能力越强。每个采样数据记录的是振幅, 采样精度取决于采样位数的大小:
packet 是一个或多个 frame 的集合,一个 packet 包含多少个 frame,是由声音文件格式决定的。譬如 PCM 文件格式中一个 packet 包含 1 个frame。而 MP3 文件格式中一个 packet 包含 1152 个frames。
比特率:也称作位速/码率,是指在一个数据流中每秒钟能通过的信息量
比特率=采样频率×采样位数×声道数

二、Audio File Services

2.1、打开或关闭音频文件

   OSStatus AudioFileOpenURL ( CFURLRef inFileRef, AudioFilePermissions inPermissions, AudioFileTypeID inFileTypeHint, AudioFileID _Nullable *outAudioFile );NSString *path = [NSString stringWithFormat:@"%@",[[NSBundle mainBundle] pathForResource:@"MySong" ofType:@"mp3"]];AudioFileID audioFileID;OSStatus status = AudioFileOpenURL((__bridge CFURLRef _Nonnull)([NSURL fileURLWithPath:path]), kAudioFileReadPermission, 0, &audioFileID);if (status != noErr) {NSLog(@"文件读取失败 %d",status);}
  • CFURLRef 文件路径;
  • AudioFilePermissions 文件读写权限 一般设置可读模式;
  • inFileTypeHint 文件类型提示 未知设置0;
  • AudioFileID 文件句柄
    AudioToolbox 函数的返回一般都是OSStatus 成功返回“noErr”,OSStatus常见错误
    CF_ENUM(OSStatus) {kAudioFileUnspecifiedError                         = 'wht?',        // 0x7768743F, 2003334207kAudioFileUnsupportedFileTypeError                 = 'typ?',        // 0x7479703F, 1954115647kAudioFileUnsupportedDataFormatError               = 'fmt?',        // 0x666D743F, 1718449215kAudioFileUnsupportedPropertyError                 = 'pty?',        // 0x7074793F, 1886681407kAudioFileBadPropertySizeError                     = '!siz',        // 0x2173697A,  561211770kAudioFilePermissionsError                         = 'prm?',        // 0x70726D3F, 1886547263kAudioFileNotOptimizedError                        = 'optm',        // 0x6F70746D, 1869640813// file format specific error codeskAudioFileInvalidChunkError                        = 'chk?',        // 0x63686B3F, 1667787583kAudioFileDoesNotAllow64BitDataSizeError               = 'off?',        // 0x6F66663F, 1868981823kAudioFileInvalidPacketOffsetError                = 'pck?',        // 0x70636B3F, 1885563711kAudioFileInvalidFileError                        = 'dta?',        // 0x6474613F, 1685348671kAudioFileOperationNotSupportedError            = 0x6F703F3F,     // 'op??', integer used because of trigraph// general file error codeskAudioFileNotOpenError                            = -38,kAudioFileEndOfFileError                        = -39,kAudioFilePositionError                            = -40,kAudioFileFileNotFoundError                        = -43
    };
    查询 OSStatus错误解释的网站OSStatus

    image.png

    与打开文件对应的close:
    @param inAudioFile 文件句柄
    OSStatus AudioFileClose ( AudioFileID inAudioFile );

2.2、 读取音频属性

获得属性的总体的大小和属性是否可以修改

OSStatus AudioFileGetPropertyInfo ( AudioFileID inAudioFile, AudioFilePropertyID inPropertyID, UInt32 *outDataSize, UInt32 *isWritable );

在获得属性的具体内容

OSStatus AudioFileGetProperty ( AudioFileID inAudioFile, AudioFilePropertyID inPropertyID, UInt32 *ioDataSize, void *outPropertyData );

使用in开头函数代表只用作输入(inAudioFile 和inPropertyID,指定了获取哪个文件和哪个属性),out开头的参数代表只用作输出(outPropertyData 指针指向的具体属性内容),io开头的参数既用作输入也用作输出(ioDataSize,接收你分配给outPropertyData的内存缓冲区的大小,然后返回实际上被写入缓冲区的大小),这种参数命名模式是AudioToolbox一个特点。可以提高对当前参数的理解。
对于isWritable为true的对其进行设置属性

OSStatus AudioFileSetProperty ( AudioFileID inAudioFile, AudioFilePropertyID inPropertyID, UInt32 inDataSize, const void *inPropertyData );

查询接口中也是一样,查询文件“inAudioFile”的“inPropertyID”的属性值,结果存放在长度为“ioDataSize”的buffer“outPropertyData”中。属性值有:

AudioFilePropertyID意义结果类型
kAudioFilePropertyFileFormat音频文件的格式char *
kAudioFilePropertyDataFormat音频数据格式AudioStreamPacketDescription
kAudioFilePropertyIsOptimized是否可以优化0/1
kAudioFilePropertyMagicCookieDataMagic Cookie文件头char *
kAudioFilePropertyAudioDataByteCount文件长度Uint64
kAudioFilePropertyAudioDataPacketCountPacket的数目Uint64
kAudioFilePropertyMaximumPacketSize最大的Packet大小Uint32
kAudioFilePropertyDataOffset数据的偏移量Uint64
kAudioFilePropertyChannelLayout声道结构AudioFormatListItem
kAudioFilePropertyDeferSizeUpdates是否更新文件头信息1/0
kAudioFilePropertyMarkerList音频中所有markersCFStringRef表示的Markers列表
kAudioFilePropertyRegionList音频中所有RegionCFStringRef表示的Region列表
kAudioFilePropertyPacketToFrame将包数转换成帧数AudioFramePacketTranslation中mPacket做输入,mFrame做输出
kAudioFilePropertyFrameToPacket将帧数转换成包数AudioFramePacketTranslation中mFrame做输入,mFrameOffsetInPacket,mPacket做输出
kAudioFilePropertyPacketToByte将包数转换成字节数AudioFramePacketTranslation中mPacket做输入,mByte做输出
kAudioFilePropertyByteToPacket将字节数转换成包数AudioFramePacketTranslation中mByte做输入,mPacket和mByteOffsetInPacket做输出
kAudioFilePropertyChunkIDs文件中的chunk编码格式4字符编码格式数组
kAudioFilePropertyInfoDictionary字典表示的InfoCFDictionary
kAudioFilePropertyPacketTableInfo设置PacketTableInfoPacketTableInfo
kAudioFilePropertyFormatList支持的格式列表编码格式list
kAudioFilePropertyPacketSizeUpperBound理论上的最大Packet大小Uint64
kAudioFilePropertyReserveDuration设置写保护区大小,单位为秒Uint32
kAudioFilePropertyEstimatedDuration估算的音频时长 , 单位秒Uint32
kAudioFilePropertyBitRate码率Uint32
kAudioFilePropertyID3TagID3 tagvoid *
kAudioFilePropertySourceBitDepth位深度Uint32
kAudioFilePropertyAlbumArtwork专辑名CFDataRef

一些音频压缩的音频格式,例如 MPEG 4 AAC,利用结构体包含音频的元数据。这些结构体就是Magic Cookie,当你用 Audio Queue Services 播放这种格式的音频文件时,你可以从音频文件中获取Magic Cookie ,然后在播放之前添加到音频队列中

 UInt32 cookieSize = sizeof (UInt32);status =  AudioFileGetPropertyInfo (audioFileID,kAudioFilePropertyMagicCookieData,&cookieSize,NULL);if (!status && cookieSize) {char* magicCookie =(char *) malloc (cookieSize);AudioFileGetProperty (audioFileID,kAudioFilePropertyMagicCookieData,&cookieSize,magicCookie);AudioQueueSetProperty (inAQ,kAudioQueueProperty_MagicCookie,magicCookie,cookieSize);free (magicCookie);}

2.3、 读取音频数据

AudioFileReadPackets 已经被废弃使用 不建议使用 主要使用的是AudioFileReadPacketData

OSStatus AudioFileReadBytes ( AudioFileID inAudioFile, Boolean inUseCache, SInt64 inStartingByte, UInt32 *ioNumBytes, void *outBuffer );
OSStatus AudioFileReadPacketData ( AudioFileID inAudioFile, Boolean inUseCache, UInt32 *ioNumBytes, AudioStreamPacketDescription *outPacketDescriptions, SInt64 inStartingPacket, UInt32 *ioNumPackets, void *outBuffer );
OSStatus AudioFileReadPackets ( AudioFileID inAudioFile, Boolean inUseCache, UInt32 *outNumBytes, AudioStreamPacketDescription *outPacketDescriptions, SInt64 inStartingPacket, UInt32 *ioNumPackets, void *outBuffer );// 已经废弃
  • AudioFileID inAudioFile 文件句柄
  • Boolean inUseCache 是否缓存读取的数据
  • UInt32 *outNumBytes : 最终读到数据的大小
  • AudioStreamPacketDescription *outPacketDescriptions : 一个存放AudioStreamPacketDescription的Buffer
  • SInt64 inStartingPacket : 起始的Packet
  • UInt32 *ioNumPackets : 当输入时表示要读取的Packet数目,输出时表示最终读入的Packet数目
  • void *outBuffer : 数据读到的具体buffer位置

三、Extended Audio File Services

Audio File Services提供的api 需要传入冗长的参数 Extended Audio File Services可以看做是对Audio File Services的封装,当时更多的实际开发我们用它来做音频文件类型的转换。

3.1、打开和关闭音频数据

打开文件:

OSStatus ExtAudioFileOpenURL ( CFURLRef inURL, ExtAudioFileRef _Nullable *outExtAudioFile );

当操作完以后,通过Dispose来回收资源,区分于其他的Close:

OSStatus ExtAudioFileDispose ( ExtAudioFileRef inExtAudioFile );

3.2、读取音频数据

和“Audio ToolBox”的其他属性操作一样,Ext接口提供的属性操作也是分为两步,先获取属性基本信息,如大小:

OSStatus ExtAudioFileGetPropertyInfo ( ExtAudioFileRef inExtAudioFile, ExtAudioFilePropertyID inPropertyID, UInt32 *outSize, Boolean *outWritable );

然后在获得属性内容:

OSStatus ExtAudioFileGetProperty ( ExtAudioFileRef inExtAudioFile, ExtAudioFilePropertyID inPropertyID, UInt32 *ioPropertyDataSize, void *outPropertyData );

或者设置属性内容:

OSStatus ExtAudioFileSetProperty ( ExtAudioFileRef inExtAudioFile, ExtAudioFilePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData );
 _outputFormat.mSampleRate = 44100;_outputFormat.mBitsPerChannel = 16;_outputFormat.mChannelsPerFrame = 2;_outputFormat.mFormatID = kAudioFormatMPEGLayer3;UInt32 descSize = sizeof(AudioStreamBasicDescription);ExtAudioFileGetProperty(_audioFileRef, kExtAudioFileProperty_FileDataFormat, &descSize, &_inputFormat);_inputFormat.mSampleRate = _outputFormat.mSampleRate;_inputFormat.mChannelsPerFrame = _outputFormat.mChannelsPerFrame;_inputFormat.mBytesPerFrame = _inputFormat.mChannelsPerFrame* _inputFormat.mBytesPerFrame;_inputFormat.mBytesPerPacket =  _inputFormat.mFramesPerPacket*_inputFormat.mBytesPerFrame;ExtAudioFileSetProperty(_audioFileRef,kExtAudioFileProperty_ClientDataFormat,sizeof(AudioStreamBasicDescription),&_inputFormat),

kExtAudioFileProperty_Xxxx : 源文件的相关属性,也就是原来什么格式的数据(MP3/AAC),他的基本属性。
kExtAudioFileProperty_ClientXxx: 读出时的数据格式,Ext在读出时会自动帮我们做编解码操作,这个是处理后的结果
所以在读取之前,一定要记得设置“kExtAudioFileProperty_ClientDataFormat”属性,设置其输出的数据格式,

ExtAudioFilePropertyID意义结果数据类型是否可读写
kExtAudioFileProperty_FileDataFormat源音频数据的格式AudioStreamBasicDescription只读
kExtAudioFileProperty_FileChannelLayout源音频数据的通道格式AudioChannelLayout读写
kExtAudioFileProperty_ClientDataFormat读出来后的音频数据的格式AudioStreamBasicDescription读写
kExtAudioFileProperty_ClientChannelLayout读出来后的音频数据的通道格式AudioChannelLayout读写
kExtAudioFileProperty_CodecManufacturer是否使用硬件编解码UInt32(kAppleHardwareAudioCodecManufacturer or kAppleSoftwareAudioCodecManufacturer)读写
kExtAudioFileProperty_AudioConverter指定的编解码工具AudioConverterRef 只读
kExtAudioFileProperty_AudioFile对应的AudioFileIDAudioFileID只读
kExtAudioFileProperty_FileMaxPacketSize源音频数据最大的Packet大小Uint32只读
kExtAudioFileProperty_ClientMaxPacketSize读出后音频数据最大的Packet大小Uint32只读
kExtAudioFileProperty_FileLengthFrames帧数 SInt64只读
kExtAudioFileProperty_ConverterConfig指定编解码器CFArray读写
kExtAudioFileProperty_IOBufferSizeBytes编解码使用的缓冲区大小UInt32读写
kExtAudioFileProperty_IOBuffer编解码使用的缓冲区void *读写
kExtAudioFileProperty_PacketTable设置PacketTableAudioFilePacketTableInfo读写
struct AudioBufferList
{UInt32      mNumberBuffers;AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements#if defined(__cplusplus) && CA_STRICT
public:AudioBufferList() {}
private://  Copying and assigning a variable length struct is problematic so turn their use into a//  compile time error for eacy spotting.AudioBufferList(const AudioBufferList&);AudioBufferList&    operator=(const AudioBufferList&);
#endif};
typedef struct AudioBufferList  AudioBufferList;struct AudioBuffer
{UInt32              mNumberChannels;UInt32              mDataByteSize;void* __nullable    mData;
};
typedef struct AudioBuffer  AudioBuffer;

写入文件内容

写入和读取类似,只是要预先填好BufferList的内容:

OSStatus ExtAudioFileWrite ( ExtAudioFileRef inExtAudioFile, UInt32 inNumberFrames, const AudioBufferList *ioData );

同时写入还有个非阻塞的版本,当调用“ ExtAudioFileDispose ”会最终保证所有数据都写入到磁盘中。

OSStatus ExtAudioFileWriteAsync ( ExtAudioFileRef inExtAudioFile, UInt32 inNumberFrames, const AudioBufferList *ioData );

四、Audio File Stream Services

对于网络音频文件 大多采用的是边读取边播放,这个时候就用到了Audio File Stream

4.1、初始化音频流

extern OSStatus    
AudioFileStreamOpen (void * __nullable                        inClientData,AudioFileStream_PropertyListenerProc    inPropertyListenerProc,AudioFileStream_PacketsProc                inPacketsProc,AudioFileTypeID                            inFileTypeHint,AudioFileStreamID __nullable * __nonnull outAudioFileStream)
  • inClientData上下文对象;
  • AudioFileStream_PropertyListenerProc 在调用AudioFileStreamParseBytes歌曲信息的回调;
  • AudioFileStream_PacketsProc 在调用AudioFileStreamParseBytes对音频数据的回调,主要用于音频帧的数据分类存储。
  • AudioFileTypeID 文件类型的提示,如果无法确定类型可以传入0
  • AudioFileStreamID,获取当前实例对应的AudioFileStreamID,使用其他AudioFileStream API需要传入。

4.2、读取音频流

extern OSStatus
AudioFileStreamParseBytes(    AudioFileStreamID                inAudioFileStream,UInt32                            inDataByteSize,const void *                    inData,AudioFileStreamParseFlags        inFlags)
  • AudioFileStreamID,AudioFileStreamOpen获取的的AudioFileStreamID;
  • inDataByteSize,解析的数据字节长度;
  • inData,解析的数据;
  • AudioFileStreamParseFlags说本次的解析和上一次解析是否是连续的关系,如果是连续的传入0,否则传kAudioFileStreamParseFlag_Discontinuity。

4.3、解析文件格式信息

typedef void (*AudioFileStream_PropertyListenerProc)(void *                            inClientData,AudioFileStreamID                inAudioFileStream,AudioFileStreamPropertyID        inPropertyID,AudioFileStreamPropertyFlags *    ioFlags);

根据当前的PropertyID调用AudioFileStreamGetProperty获取当前音频文件的具体信息

if (inPropertyID ==  kAudioFileStreamProperty_DataFormat) {UInt32 outDataSize = sizeof(AudioStreamBasicDescription);AudioFileStreamGetProperty(inAudioFileStream, inPropertyID,  &outDataSize, &_audioStreamDescription);}
typedef void (*AudioFileStream_PacketsProc)(void *                            inClientData,UInt32                            inNumberBytes,UInt32                            inNumberPackets,const void *                    inInputData,AudioStreamPacketDescription    *inPacketDescriptions);
  • inClientData 上下文对象;
  • inumberOfBytes,读取的数据长度;
  • inumberOfPackets,读取的数据帧数量;
  • inInputData,读取的数据字节;
  • AudioStreamPacketDescription类型的数组,存储了当前帧数据的偏移量和大小。

图片来源:Audio Streaming ( Audio Queue )

五、Audio Queue Services

5.1、初始化Audio Queue

AudioQueueNewOutput(                const AudioStreamBasicDescription *inFormat,AudioQueueOutputCallback        inCallbackProc,void * __nullable               inUserData,CFRunLoopRef __nullable         inCallbackRunLoop,CFStringRef __nullable          inCallbackRunLoopMode,UInt32                          inFlags,AudioQueueRef __nullable * __nonnull outAQ)
  • AudioStreamBasicDescription音频数据格式类型,是一个AudioStreamBasicDescription对象,是使用AudioFileStream或者AudioFile解析出来的数据格式信息;
  • AudioQueueOutputCallback是某块Buffer被使用之后的回调;
  • inUserData 上下文对象;
  • inCallbackRunLoop为AudioQueueOutputCallback需要在的哪个RunLoop上被回调,如果传入NULL的话就会再AudioQueue的内部RunLoop中被回调,所以一般传NULL就可以了;
  • inCallbackRunLoopMode为RunLoop模式,如果传入NULL就相当于kCFRunLoopCommonModes,也传NULL就可以了;
  • inFlags是保留字段,目前没作用,传0;
  • 返回生成的AudioQueue实例;

5.2、创建buffer

extern OSStatus
AudioQueueAllocateBuffer(           AudioQueueRef           inAQ,UInt32                  inBufferByteSize,AudioQueueBufferRef __nullable * __nonnull outBuffer)
  • AudioQueueRef 创建的AudioQueue
  • inBufferByteSize buffer的大小
  • AudioQueueBufferRef 返回当前创建的buffer实例。

5.3、将buffer放入音频队列

extern OSStatus
AudioQueueEnqueueBuffer(            AudioQueueRef                       inAQ,AudioQueueBufferRef                 inBuffer,UInt32                              inNumPacketDescs,const AudioStreamPacketDescription * __nullable inPacketDescs)
  • AudioQueueRef 创建的AudioQueue
  • AudioQueueBufferRef buffer对象
  • AudioStreamPacketDescription数组的数量
  • AudioStreamPacketDescription数组的指针地址


作者:baxiang
链接:http://www.jianshu.com/p/3a92e0c7bf74
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章:

【WA】九度OJ题目1435:迷瘴

题目描述: 通过悬崖的yifenfei,又面临着幽谷的考验——幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。幸好y…

云端应用SQL注入攻击

实验目的及要求: 完成VMware Workstations14平台安装,会应用相关操作;完成Windows server2008R2操作系统及Kali Linux操作系统的安装;掌握SQLmap攻击工具的使用;使用SQLmap对目标站点进行渗透攻击; 实验环…

SPOJ375(树链剖分)

题目:Query on a tree 题意:给定一棵树,告诉了每条边的权值,然后给出两种操作: (1)把第i条边的权值改为val (2)询问a,b路径上权值最大的边 分析:本题与HDU3966差不多,区别就是&#…

简单的python服务器程序

一个接受telnet输入的服务器端小程序 #!/usr/local/bin/python3.5 #coding:utf-8 import sockethost port 51423s socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((host, port)) s.listen(1)print(S…

iOS:一句代码实现文本输入的限制

前言 实际开发中,往往需要处理UITextView、UITextField输入的限制。比如输入必须是价格格式(一个小数点、小数点后面最多两位);输入最大长度限制;对输入内容的实时回调。处理这些的时候,我们通常需要做一些…

Linux操作系统(一:基本操作)

1、创建一个以自己姓名拼音简写一致的用户名( useradd -d /home/abc abc) 2、在linux中使用打印命令,在命令行中输入“当前用户名Hello world !” 3、显示现在天年月日,显示后一天的日期,显示上一月日期,显…

Core Text 学习笔记-基础

前言 最近在学习YYKit框架,看到关于CoreText相关的知识的时候感到非常吃力,于是乎就恶补了一下Core Text相关的基础知识。 Glyphs(字形) 字符的图形形式, 则是文字中字母 (character) 的视觉表现。(字形&am…

虚拟机下CentOS 6.5配置IP地址的三种方法

实验软件环境:虚拟机Vmware Workstation10.0 、CentOS 6.5 32位 1、自动获取IP地址 虚拟机使用桥接模式,相当于连接到物理机的网络里,物理机网络有DHCP服务器自动分配IP地址。 dhclient 自动获取ip地址命令 ifconfig 查询系统里网卡信息&…

GIS 相关知识扫盲

1、什么是GIS GIS:地理信息系统,它是一种特定的十分重要的空间信息系统。它是在计算机硬、软件系统支持下,对整个或部分地球表层(包括大气层)空间中的有关地理分布数据进行采集、储存、管理、运算、分析、显示和描述的技术系统。2…

Linux操作系统(二:shell脚本)

练习一:编写shell脚本,计算1-100的和; 练习二:将一目录下所有的文件的扩展名改为bak 练习三:写一个脚本,统计。/etc/ 目录下共有多少个目录文件 练习四:写一个脚本,依次向/etc/passw…

用OpenGLES实现yuv420p视频播放界面

背景 例子TFLive这个项目里,是我按着ijkPlayer写的直播播放器,要运行需要编译ffmpeg的库,网盘里存了一份, 提取码:vjce。OpenGL ES播放相关的在在OpenGLES的文件夹里。 learnOpenGL学到会使用纹理就可以了。 播放视频,就是把画面一…

C++类的静态成员详细讲解

在C中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。 静态成员的定义或声明要…

jenkins2 multibranch

通过multibranch类型的pipeline job使得对于多个branch的支持更加简单。只需要创建一个multibranch job,jenkins将自动地为所有的branch创建job。 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://github.com/ciand…

Nagios的安装和基本配置(一:知识点总结及环境准备)

实验目的及要求 掌握Nagios监控的基本使用;掌握Nagios监控服务的搭建和配置; 实验环境: 1、满足实验要求的PC端; Host-name OS IP sofaware Nagios-server Centos7 192.168.1.119 Apache,php,Nagios,Nagios-plguins Nag…

浅谈Android四大组件之Service

一:Service简介 Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service。 1:Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切…

使用 fastlane 实现 iOS 持续集成(二)

本文接上篇文章主要说下怎样使用 fastlane 上传到fir和蒲公英,下面先介绍下 plugin 命令。 plugin命令介绍: 列出所有可用插件 fastlane search_plugins 搜索指定名称的插件: fastlane search_plugins [query] 添加插件: fastlane add_plugin [name] 安装插件: fast…

Nagios的安装和基本配置(二:Nagios-Server的安装)

任务二、Nagios-server的安装 2.1、创建Nagios用户和组 注: #useradd Nagios -s /bin/nologin #groundadd nagcmd #usermod -a -G nagcmd Nagios #usermod -a G nagcmd apache 2.2、安装Nagios 2.2.1、上传软件包至操作系统中; 2.2.2、解压软件并…

shell编程-正则表达式

1.正则表达式是什么 它主要用于字符串的模式分割,匹配,查找及替换操作。 2、正则表达式与通配符 正则表达式用来在文件中匹配符合条件的字符串,正则包含匹配。grep,awk,sed等命令可以支持正则表达式。 通配符用来匹配符合条件的文件名&#x…

使用 CocoaPods 给微信集成 SDK 打印收发消息

推荐序 本文介绍的是一套逆向工具,可以在非越狱手机上给任意应用增加插件。在文末的示例中,作者拿微信举例,展示出在微信中打印收发消息的功能。 这套工具可以加快逆向开发的速度,其重签名思想也可以用于二次分发别人的应用。 其实…

数据库之子查询四(多重,表复制)

一、多重子查询 select teaID,teaName,age,sex,dept,professionfrom tteacherwhere dept(select dept from teaIDt103265)and profession(select professionfrom tteacherwhere teaIDt103265)这里的子查询就是为了从表中提取出有效信息参与外部查询二、create table 语句中子查…

Nagios的安装和基本配置(三:Nagios-Client的安装)

任务三、Nagios-Client的安装 3.1、关闭防火墙和selinux 注: #systemctl stop firewalld.service #systemctl disable firewalld.service #vi /etc/selinux/config 3.2、配置环境 #yum install gcc glibc-common -y #yum install gd gd-devel openssl openssl…

事件(待完成)

内容窗口 事件绑定​ 给整个浏览器 内容窗口区的事件绑定。 ​通过 document.documentElement或者document.body?似乎都可以。但最好是直接通过document document.addEventListener(mousemove,function () { });// 整个浏览器内容范围都将触发。拖动实现必用​ 转载…

iOS 模仿支付宝支付到账推送,播报钱数

最近申请了支付宝的二维码收钱码,其中支付宝有这么一个功能,就是,别人扫描你的二维码给你转账之后,收到钱会有一条语音推送,”支付宝到账 1000万“之类的推送消息,不管你的支付宝app有没有被杀死。 只要你的…

hdu - 4707 - Pet

题意&#xff1a;一棵N个结点(编号从0开始)的树&#xff0c;根结点为0&#xff0c;求到根结点的距离大于D的结点个数&#xff08;0 < 测试组数T < 10, 0<N<100000, 0<D<N&#xff09;。 题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid4707…

Nagios的安装和基本配置(四:调试验证 错误总结)

任务四、调试验证 4.1、验证连通性 在/usr/local/Nagios/etc/nrpe.cfg文件中server的ip地址 #vi /usr/local/Nagios/etc/nrpe.cfg #重启nrpe #pkill nrpe #netstat -Intp #/usr/local/Nagios/bin/nrpe -d -c /usr/local/Nagios/etc/nrpe.cfg #在server主机做验证 #cd /…

hitTest和pointInside方法

hittest方法 就是用来寻找最合适的view当一个事件传递给一个控件&#xff0c;就会调用这个控件的hitTest方法点击了白色的view&#xff1a; 触摸事件 -> UIApplication -> UIWindow 调用 [UIWindow hitTest] -> 白色view [WhteView hitTest] 实验1: 定义 BaseView&…

Github上的PHP资源汇总大全

依赖管理 ——用于依赖管理的包和框架 Composer/Packagist : 一个包和依赖管理器 Composer Installers: 一个多框架Composer库安装器 Pickle: 可以在任意平台上安装PHP扩展包 依赖管理的附加部分 ——其它依赖管理的相关工具 Satis : 静态的Composer库生成器 Composition: 一个…

UIButton长按事件

添加长按事件1 - (void)viewDidLoad2 {3 [super viewDidLoad];4 //Do any additional setup after loading the view, typically from a nib.5 6 UIButton *aBtn[UIButton buttonWithType:UIButtonTypeRoundedRect];7 [aBtn setFrame:CGRectMake(0, 10, 60, 60…

Hadoop集群搭建(一:集群安装及网络环境配置)

实验目的及要求 完成VMware workstations安装&#xff0c;会应用相关操作&#xff1b;完成虚拟机中Linux CentOS 7操作系统安装&#xff1b;完成静态网络地址的配置&#xff0c;所有主机的网络能够正常使用&#xff0c;相互之间能够正常连接&#xff1b;完成主机名配置&#x…

QQ音乐API分析记录

我一直是QQ音乐的用户&#xff0c;最近想做一个应用&#xff0c;想用QQ音乐的API&#xff0c;搜索了很久无果&#xff0c;于是就自己分析QQ音乐的API。 前不久发现QQ音乐出了网页版的&#xff0c;是Flash的&#xff0c;但是&#xff0c;我用iPhone打开这个链接的时候&#xff0…