目錄
一、音頻
1.音頻播放
2.錄音
3.訊飛語(yǔ)音的使用二标沪、視頻
1.視頻播放
2.視頻開(kāi)發(fā)
一苞轿、音頻
1.音頻播放
iOS開(kāi)發(fā)中的音頻播放大致分為兩類(lèi):一種是短音頻(通常稱(chēng)為音效逗物,時(shí)長(zhǎng)不超過(guò)30s),一種是長(zhǎng)音頻(通常稱(chēng)為音樂(lè))瑟俭。前者通臭嶙浚可以通過(guò)AudioToolbox.framework進(jìn)行操作(由一系列C語(yǔ)言的函數(shù)構(gòu)成)摆寄,后者要使用AVFoundation.framework(用Objective-C封裝好的一系列的類(lèi))失暴。?播放音效(短音頻)通常打包成.caf、.aif和.wav格式微饥。下面為大家封裝了一段播放音頻的代碼,由于音頻播放的AudioToolBox底層都是C函數(shù)欠橘,所以使用了函數(shù)指針矩肩,不熟悉的可以翻翻之前C的東西
- (void)playSoundEffect:(NSString *)name withCallback:(void (*)(SystemSoundID, void *)) callback {
NSString *audioFile = [[NSBundle mainBundle] pathForResource:name ofType:nil];
NSURL *fileUrl = [NSURL fileURLWithPath:audioFile];
SystemSoundID soundID;
// 在系統(tǒng)中創(chuàng)建一個(gè)音效對(duì)象并獲得其唯一ID
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
// 注冊(cè)在播放完之后執(zhí)行的回調(diào)函數(shù)
// 第二個(gè)和第三個(gè)參數(shù)跟循環(huán)播放有關(guān)
// 第五個(gè)參數(shù)是指向傳給回調(diào)函數(shù)的數(shù)據(jù)的指針
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, callback, NULL);
// 播放音效
AudioServicesPlaySystemSound(soundID);
// 播放音效并震動(dòng)
// AudioServicesPlayAlertSound(soundID);
}
播放音樂(lè)可以使用AVAudioPlayer類(lèi):
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:@"后會(huì)無(wú)期" ofType:@"mp3"];
NSURL *url = [NSURL fileURLWithPath:path];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
self.player.volume = 5;
self.player.delegate = self;
[self.player prepareToPlay];
[self.player play];
Demo代碼如下:
2.錄音
使用AVAudioRecorder可以實(shí)現(xiàn)錄音功能肃续。
代碼如下:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:AVAudioQualityLow], AVEncoderAudioQualityKey,
[NSNumber numberWithInt:16], AVEncoderBitRateKey,
[NSNumber numberWithInt:2],AVNumberOfChannelsKey,
[NSNumber numberWithFloat:44100.0],AVSampleRateKey,
nil
];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/record.caf", [[NSBundle mainBundle] resourcePath]]];
self.recorder = [[AVAudioRecorder alloc] initWithURL:url settings:dict error:nil];
[self.recorder prepareToRecord];
Demo代碼如下:
3.訊飛語(yǔ)音的使用
在移動(dòng)應(yīng)用中使用語(yǔ)音識(shí)別功能后叉袍,原來(lái)需要鍵盤(pán)輸入的地方可以直接使用語(yǔ)音進(jìn)行輸入刽酱,從而解放用戶(hù)的雙手提供更好的用戶(hù)體驗(yàn)喳逛。目前訊飛MSC在中文語(yǔ)音識(shí)別中用得較多,下面就以訊飛語(yǔ)音識(shí)別為例講解如何實(shí)現(xiàn)語(yǔ)音搜索功能棵里。可以在訊飛開(kāi)放平臺(tái)的SDK下載中心下載訊飛提供的語(yǔ)音聽(tīng)寫(xiě)功能殿怜,當(dāng)然需要注冊(cè)賬號(hào)并獲得使用SDK的APPID转唉,下載后的文件夾中包含了文檔稳捆、庫(kù)文件和樣例程序赠法,可以直接閱讀文檔或參考樣例程序來(lái)實(shí)現(xiàn)自己的語(yǔ)音搜索功能乔夯。創(chuàng)建項(xiàng)目后砖织,需要向項(xiàng)目中加入訊飛的庫(kù)文件以及它依賴(lài)的其他庫(kù)文件末荐,可以在下圖所示的位置進(jìn)行添加侧纯,需要添加的庫(kù)文件也如下圖所示,其他的庫(kù)文件可以通過(guò)Xcode的自動(dòng)鏈接器自動(dòng)加入眶熬。
可以對(duì)訊飛提供的SDK進(jìn)行二次封裝,使其變成更容易使用的API(只用一行代碼就可以使用它的功能)块请,代碼如下所示:
上面的代碼在訊飛提供的樣例程序中可以找到,無(wú)需自行編寫(xiě)墩新,但是可以對(duì)其中的一些參數(shù)進(jìn)行設(shè)置贸弥,例如language(語(yǔ)種)、vadEos(語(yǔ)音結(jié)束后的超時(shí)點(diǎn))绵疲、vadBos(語(yǔ)音開(kāi)始前的超時(shí)點(diǎn))、speechTimeout(語(yǔ)音長(zhǎng)度達(dá)到多少時(shí)間超時(shí))等臣疑。
.h文件
#import <Foundation/Foundation.h>
#import "iflyMSC/IFlyMSC.h"
typedef void(^CDVoiceHandler)(NSString *);
@interface CDVoice : NSObject <IFlyRecognizerViewDelegate> {
IFlyRecognizerView *rView;
}
@property (nonatomic, copy) CDVoiceHandler voiceHandler;
+ (instancetype) sharedInstance;
- (void) voiceToTextString:(CDVoiceHandler) handler;
@end
.m文件
#import "CDVoice.h"
#import "IATConfig.h"
#define LEFT_FOR_RV 50#define TOP_FOR_RV 50
@implementation CDVoice
- (instancetype) init {
@throw [NSException exceptionWithName:@"CDVoiceException" reason:@"不允許使用初始化方法" userInfo:nil];
}
- (instancetype) initPrivate {
if (self = [super init]) {
// Do some initialization here!!!
} return self;
}
+ (instancetype) sharedInstance {
static CDVoice *instance = nil;
if (!instance) {
instance = [[self alloc] initPrivate];
} return instance;
}
- (void) voiceToTextString:(CDVoiceHandler) handler{
if (!rView) {
rView = [[IFlyRecognizerView alloc] initWithOrigin:CGPointMake(LEFT_FOR_RV, TOP_FOR_RV)];
[rView setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];
//設(shè)置聽(tīng)寫(xiě)模式
[rView setParameter:@"iat" forKey:[IFlySpeechConstant IFLY_DOMAIN]];
rView.delegate = self;
IATConfig *instance = [IATConfig sharedInstance];
//設(shè)置最長(zhǎng)錄音時(shí)間
[rView setParameter:instance.speechTimeout forKey:[IFlySpeechConstant SPEECH_TIMEOUT]];
//設(shè)置后端點(diǎn)
[rView setParameter:instance.vadEos forKey: [IFlySpeechConstant VAD_EOS]];
//設(shè)置前端點(diǎn)
[rView setParameter:instance.vadBos forKey:[IFlySpeechConstant VAD_BOS]];
//設(shè)置采樣率盔憨,推薦使用16K
[rView setParameter:instance.sampleRate forKey:[IFlySpeechConstant SAMPLE_RATE]];
if ([instance.language isEqualToString:[IATConfig chinese]]) {
//設(shè)置語(yǔ)言
[rView setParameter:instance.language forKey:[IFlySpeechConstant LANGUAGE]];
//設(shè)置方言
[rView setParameter:instance.accent forKey:[IFlySpeechConstant ACCENT]];
} else if ([instance.language isEqualToString:[IATConfig english]]) {
//設(shè)置語(yǔ)言
[rView setParameter:instance.language forKey:[IFlySpeechConstant LANGUAGE]];
}
//設(shè)置是否返回標(biāo)點(diǎn)符號(hào)
[rView setParameter:instance.dot forKey:[IFlySpeechConstant ASR_PTT]];
}
// 綁定語(yǔ)音識(shí)別完成后做回調(diào)的Block
self.voiceHandler = handler;
[rView start];
}
// 語(yǔ)音識(shí)別完成的回調(diào)
- (void)onResult:(NSArray *)resultArray isLast:(BOOL) isLast {
NSMutableString *result = [[NSMutableString alloc] init];
NSMutableString * resultString = [[NSMutableString alloc]init];
NSDictionary *dic = resultArray[0];
for (NSString *key in dic) {
[result appendFormat:@"%@",key];
NSString * resultFromJson = [self stringFromABNFJson:result];
if (! [resultString isEqualToString:@" "]) {
[resultString appendString:resultFromJson];
}
}
if (!isLast && self.voiceHandler) {
self.voiceHandler(resultString);
}
}
// 語(yǔ)音識(shí)別出錯(cuò)的回調(diào)方法
- (void)onError: (IFlySpeechError *) error {
if (error.errorCode) {
NSLog(@"%@", error);
}
}
// 從JSON格式的數(shù)據(jù)中提取語(yǔ)音數(shù)據(jù)(該方法可以在官方Demo的代碼中找到)
- (NSString *)stringFromABNFJson: (NSString *) params {
if (!params) {
return nil;
}
NSMutableString *tempStr = [[NSMutableString alloc] init];
NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:[params dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
NSArray *wordArray = [resultDic objectForKey:@"ws"];
for (int i = 0; i < [wordArray count]; i++) {
NSDictionary *wsDic = [wordArray objectAtIndex: i];
NSArray *cwArray = [wsDic objectForKey:@"cw"];
for (int j = 0; j < [cwArray count]; j++) {
NSDictionary *wDic = [cwArray objectAtIndex:j];
NSString *str = [wDic objectForKey:@"w"]; [tempStr appendString: str];
}
}
return tempStr;
}
@end
到此為止讯沈,我們已經(jīng)封裝好了自己的API,要使用它非常簡(jiǎn)單,代碼如下所示:
#import "AppDelegate.h"
#import "iflyMSC/IFlyMSC.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 將自己申請(qǐng)的APPID通過(guò)IFlySpeechUtility工具類(lèi)進(jìn)行注冊(cè)
[IFlySpeechUtility createUtility:@"appid=自己申請(qǐng)的APPID"];
return YES;
}
@end
舉例 - 下面完成了一個(gè)非常簡(jiǎn)單的應(yīng)用來(lái)使用我們封裝好的語(yǔ)音識(shí)別功能:
運(yùn)行效果如下圖所示驯用,點(diǎn)擊OK按鈕開(kāi)始進(jìn)行語(yǔ)音識(shí)別,完成后將識(shí)別的內(nèi)容輸入文本框中:
我們可以對(duì)搜索欄中的書(shū)簽按鈕進(jìn)行定制蝴乔,在點(diǎn)擊通過(guò)調(diào)用我們封裝好的代碼后產(chǎn)生語(yǔ)音識(shí)別的視圖记餐,然后將識(shí)別的結(jié)果填入搜索欄中:
- (void) customizeSearchBar {
mySearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 0, 40)];
mySearchBar.placeholder = @"請(qǐng)輸入要查找的名字";
mySearchBar.showsCancelButton = YES;
mySearchBar.showsBookmarkButton = YES;
[mySearchBar setImage:[UIImage imageNamed:@"Dudu.jpg"] forSearchBarIcon:UISearchBarIconBookmark state:UIControlStateNormal];
mySearchBar.delegate = self;
[myTableView setTableHeaderView:mySearchBar];
}
// 點(diǎn)擊書(shū)簽按鈕的回調(diào)方法
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar {
[[CDVoice sharedInstance] voiceToTextString:^(NSString *str) {
mySearchBar.text = str;
[mySearchBar becomeFirstResponder];
}];
}
二薇正、視頻
1.視頻播放
2.視頻開(kāi)發(fā)
相關(guān)鏈接:https://pan.baidu.com/s/16Hn_8ryr6F9AquCHD7hKhg 提取碼: fjni
ZSPlayerDemo:https://github.com/wuyubeichen/ZSPlayerDemo