1.播放音效
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h> //播放音頻需要用到的框架
@interface ViewController ()
@property (nonatomic, assign) SystemSoundID soundID;
@end
@implementation ViewController
//音效
//又稱“短音頻”配乓,通常在程序中的播放時長為1~2秒
//在應用程序中起到點綴效果州泊,提升整體用戶體驗
- (void)playSound{
// 1.獲得音效文件的全路徑
NSURL *url = [[NSBundle mainBundle] URLForResource:@"buyao.wav" withExtension:nil];
// 2.加載音效文件, 創(chuàng)建音效ID(SoundID)
AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &_soundID);
// 3.播放音效
AudioServicesPlaySystemSound(_soundID);
}
@end
2.播放音樂
類方法不能訪問成員屬性,只能訪問 static NSMutableDictionary *_musicPlayers; 靜態(tài)變量
ZYXAudioTool.h
#import <Foundation/Foundation.h>
@interface ZYXAudioTool : NSObject
/**
* 播放音效
*
* @param filename 音效的文件名
*/
+ (void)playSound:(NSString *)filename;
/**
* 銷毀音效
*
* @param filename 音效的文件名
*/
+ (void)disposeSound:(NSString *)filename;
/**
* 播放音樂
*
* @param filename 音樂的文件名
*/
+ (BOOL)playMusic:(NSString *)filename;
/**
* 暫停音樂
*
* @param filename 音樂的文件名
*/
+ (void)pauseMusic:(NSString *)filename;
/**
* 停止音樂
*
* @param filename 音樂的文件名
*/
+ (void)stopMusic:(NSString *)filename;
@end
ZYXAudioTool.m
#import "ZYXAudioTool.h"
#import <AVFoundation/AVFoundation.h>
@implementation ZYXAudioTool
#pragma mark - 存放所有的音效ID
static NSMutableDictionary *_soundIDs;
+ (NSMutableDictionary *)soundIDs
{
if (!_soundIDs) {
_soundIDs = [NSMutableDictionary dictionary];
}
return _soundIDs;
}
#pragma mark - 播放音效 @param filename 音效的文件名
+ (void)playSound:(NSString *)filename
{
if (!filename) return;
// 1.取出對應的音效ID
SystemSoundID soundID = [[self soundIDs][filename] intValue];
// 2.初始化 音效文件只需要加載1次
if (!soundID) {
// 1.音頻文件的URL
NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
if (!url) return;
// 2.加載音效文件篙耗,得到對應的音效ID
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
// 存入字典
[self soundIDs][filename] = @(soundID);
}
// 3.播放
AudioServicesPlaySystemSound(soundID);
}
#pragma mark - 銷毀音效 @param filename 音效的文件名
+ (void)disposeSound:(NSString *)filename
{
if (!filename) return;
// 1.取出對應的音效ID
SystemSoundID soundID = [[self soundIDs][filename] intValue];
// 2.銷毀
if (soundID) {
// 釋放音效資源
AudioServicesDisposeSystemSoundID(soundID);
[[self soundIDs] removeObjectForKey:filename];
}
}
#pragma mark - 存放所有的音樂播放器
static NSMutableDictionary *_musicPlayers;
+ (NSMutableDictionary *)musicPlayers
{
if (!_musicPlayers) {
_musicPlayers = [NSMutableDictionary dictionary];
}
return _musicPlayers;
}
#pragma mark - 播放音樂 @param filename 音樂的文件名
+ (BOOL)playMusic:(NSString *)filename
{
if (!filename) return NO;
// 1.取出對應的播放器
AVAudioPlayer *player = [self musicPlayers][filename];
// 2.播放器沒有創(chuàng)建,進行初始化
if (!player) {
// 音頻文件的URL
NSURL *url = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
if (!url) return NO;
// 創(chuàng)建播放器(一個AVAudioPlayer只能播放一個URL)
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
// 緩沖
if (![player prepareToPlay]) return NO;
// 存入字典
[self musicPlayers][filename] = player;
}
// 3.播放
if (!player.isPlaying) {
return [player play];
}
// 正在播放
return YES;
}
#pragma mark - 暫停音樂 @param filename 音樂的文件名
+ (void)pauseMusic:(NSString *)filename
{
if (!filename) return;
// 1.取出對應的播放器
AVAudioPlayer *player = [self musicPlayers][filename];
// 2.暫停
if (player.isPlaying) {
[player pause];
}
}
#pragma mark - 停止音樂 @param filename 音樂的文件名
+ (void)stopMusic:(NSString *)filename
{
if (!filename) return;
// 1.取出對應的播放器
AVAudioPlayer *player = [self musicPlayers][filename];
// 2.停止
[player stop];
// 3.將播放器從字典中移除
[[self musicPlayers] removeObjectForKey:filename];
}
@end
ViewController.m
#import "ViewController.h"
#import "ZYXAudioTool.h"
@interface ViewController ()
- (IBAction)play;
- (IBAction)pause;
- (IBAction)stop;
- (IBAction)next;
@property (nonatomic, strong) NSArray *songs;
@property (nonatomic, assign) int currentIndex;
@end
@implementation ViewController
- (NSArray *)songs{
if (!_songs) {
self.songs = @[@"120125029.mp3", @"309769.mp3", @"235319.mp3"];
}
return _songs;
}
- (IBAction)play {
[ZYXAudioTool playMusic:self.songs[self.currentIndex]];
}
- (IBAction)pause {
[ZYXAudioTool pauseMusic:self.songs[self.currentIndex]];
}
- (IBAction)stop {
[ZYXAudioTool stopMusic:self.songs[self.currentIndex]];
}
- (IBAction)next {
[self stop];
self.currentIndex++;
if (self.currentIndex >= self.songs.count) {
self.currentIndex = 0;
}
[self play];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[ZYXAudioTool playSound:@"buyao.wav"];
}
@end
3.本地和網(wǎng)絡流媒體音頻視頻播放
AVPlayer
播放本地/網(wǎng)絡 音頻 視頻
MPMoviePlayerController
播放本地/網(wǎng)絡 音頻 視頻
MPMoviePlayerViewController
播放本地/網(wǎng)絡 音頻 視頻
ViewController.m
#import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@property (nonatomic, strong) MPMoviePlayerController *mpc;
@property (nonatomic, strong) AVPlayer *player;
@end
@implementation ViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self networkVideo];
}
-(void)viewDidLoad
{
[super viewDidLoad];
[self avPlayer];
[self moviePlayerController];
}
- (void)avPlayer{
NSURL *url = nil;
#pragma mark - local
url = [[NSBundle mainBundle] URLForResource:@"minion_01.mp4" withExtension:nil];
#pragma mark - network
url = [NSURL URLWithString:@"http://localhost/videos/235319.mp3"];
url = [NSURL URLWithString:@"http://localhost/videos/minion_15.mp4"];
// 創(chuàng)建播放器
AVPlayer *player = [AVPlayer playerWithURL:url];
[player play];
// 創(chuàng)建播放器圖層
AVPlayerLayer *layer = [AVPlayerLayer layer];
layer.player = player;
layer.frame = CGRectMake(10, 20, 300, 200);
// 添加圖層到控制器的view
[self.view.layer addSublayer:layer];
}
- (void)moviePlayerController{
// 創(chuàng)建播放器對象
MPMoviePlayerController *mpc = [[MPMoviePlayerController alloc] init];
#pragma mark - local
mpc.contentURL = [[NSBundle mainBundle] URLForResource:@"minion_01.mp4" withExtension:nil];
#pragma mark - network
mpc.contentURL = [NSURL URLWithString:@"http://localhost/videos/235319.mp3"];
mpc.contentURL = [NSURL URLWithString:@"http://localhost/videos/minion_15.mp4"];
// 添加播放器界面到控制器的view上面
mpc.view.frame = CGRectMake(10, self.view.frame.size.height-240, 300, 200);
[self.view addSubview:mpc.view];
UIView *controlView = [[UIView alloc] init];
controlView.backgroundColor = [UIColor redColor];
controlView.frame = CGRectMake(0, 0, 300, 50);
[mpc.view addSubview:controlView];
// 隱藏自動自帶的控制面板
mpc.controlStyle = MPMovieControlStyleNone;
// 監(jiān)聽播放器
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(movieStateDidChange)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:mpc];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(movieDidFinish)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mpc];
[mpc play];
self.mpc = mpc;
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)movieStateDidChange{
NSLog(@"----播放狀態(tài)--%ld", (long)self.mpc.playbackState);
}
- (void)movieDidFinish{
NSLog(@"----播放完畢");
}
// ----播放狀態(tài)--1
// ----播放狀態(tài)--2
// ----播放完畢
#pragma mark - network
- (void)networkVideo{
// MPMoviePlayerViewController繼承自UIViewController猿诸,它內(nèi)部封裝了一個MPMoviePlayerController
// MPMoviePlayerViewController只能全屏播放
// NSURL *url = [NSURL URLWithString:@"http://streams.videolan.org/streams/mp4/Mr_MrsSmith-h264_aac.mp4"];
NSURL *url = [NSURL URLWithString:@"http://localhost/videos/minion_01.mp4"];
MPMoviePlayerViewController *mpvc = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[self presentMoviePlayerViewControllerAnimated:mpvc];
}
@end
4.VLC框架本地和網(wǎng)絡流媒體音頻視頻播放
ViewController.m
#import "ViewController.h"
#import <MobileVLCKit/MobileVLCKit.h>
@interface ViewController ()
@property (nonatomic, strong) VLCMediaPlayer *player;
@end
@implementation ViewController
- (void)vlcPlayer{
self.player = [[VLCMediaPlayer alloc] init];
// 設置需要播放的多媒體文件
// @"http://streams.videolan.org/streams/mp4/Mr_MrsSmith-h264_aac.mp4"
// @"http://y1.eoews.com/assets/ringtones/2012/5/18/34045/hi4dwfmrxm2citwjcc5841z3tiqaeeoczhbtfoex.mp3"
NSURL *url = nil;
#pragma mark - local
url = [[NSBundle mainBundle] URLForResource:@"minion_01.mp4" withExtension:nil];
#pragma mark - network
url = [NSURL URLWithString:@"http://localhost/videos/235319.mp3"];
url = [NSURL URLWithString:@"http://localhost/videos/minion_15.mp4"];
self.player.media = [VLCMedia mediaWithURL:url];
// 設置播放界面的載體
self.player.drawable = self.view;
// 播放
[self.player play];
}
@end
5.AVAudioRecorder錄音
ViewController.m
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
- (IBAction)startRecord;
- (IBAction)stopRecord;
@property (nonatomic, strong) AVAudioRecorder *recorder;
@property (nonatomic, strong) CADisplayLink *link;
@property (nonatomic, assign) double slientDuration;
@end
@implementation ViewController
- (CADisplayLink *)link
{
if (!_link) {
self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
}
return _link;
}
- (void)update
{
// 1.更新錄音器的測量值
[self.recorder updateMeters];
// 2.獲得平均分貝
float power = [self.recorder averagePowerForChannel:0];
// 3.如果小于-30, 開始靜音
if (power < -30) {
if ([self.recorder isRecording]) {
[self.recorder pause];
}
self.slientDuration += self.link.duration;
if (self.slientDuration >= 2) { // 沉默至少2秒鐘
[self.recorder stop];
// 停止定時器
[self.link invalidate];
self.link = nil;
NSLog(@"--------停止錄音");
}
} else {
if (![self.recorder isRecording]) {
[self.recorder record];
}
self.slientDuration = 0;
NSLog(@"**********持續(xù)說話");
}
}
- (IBAction)startRecord {
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:@"zyx.caf"];
NSLog(@"path = %@",path);
NSURL *url = [NSURL fileURLWithPath:path];
// 1.創(chuàng)建錄音器
NSMutableDictionary *setting = [NSMutableDictionary dictionary];
// 音頻格式
setting[AVFormatIDKey] = @(kAudioFormatAppleIMA4);
// 音頻采樣率
setting[AVSampleRateKey] = @(8000.0);
// 音頻通道數(shù)
setting[AVNumberOfChannelsKey] = @(1);
// 線性音頻的位深度
setting[AVLinearPCMBitDepthKey] = @(8);
AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:nil];
// 允許測量分貝
recorder.meteringEnabled = YES;
// 2.緩沖
[recorder prepareToRecord];
// 3.錄音
[recorder record];
self.recorder = recorder;
// 4.開啟定時器
self.slientDuration = 0;
[self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
- (IBAction)stopRecord {
[self.recorder stop];
}
@end
6.錄音和播放代理
AVAudioRecorderDelegate
AVAudioPlayerDelegate
ViewController.m
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#define kMoniterFile @"monitor.caf"
#define kRecorderFile @"recorder.caf"
#define kRecorderPower -25.0
@interface ViewController () <AVAudioRecorderDelegate, AVAudioPlayerDelegate>
{
AVAudioRecorder *_monitor; // 監(jiān)聽器
AVAudioRecorder *_recorder; // 錄音機
AVAudioPlayer *_player; // 播放器
NSTimer *_timer; // 時鐘
NSTimeInterval _silenceDuration; // 累計靜音時長
NSDate *_lastRecorderTime; // 末次錄音時間
}
@end
@implementation ViewController
#pragma mark - 私有方法
#pragma mark - 錄音設置
- (NSDictionary *)recorderSettings{
NSMutableDictionary *setting = [[NSMutableDictionary alloc] init];
// 音頻格式
[setting setValue:[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
// 音頻采樣率
[setting setValue:[NSNumber numberWithFloat:8000.0] forKey:AVSampleRateKey];
// 音頻通道數(shù)
[setting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
// 線性音頻的位深度
[setting setValue:[NSNumber numberWithInt:8] forKey:AVLinearPCMBitDepthKey];
return setting;
}
#pragma mark - 創(chuàng)建URL
- (NSURL *)urlWithFileName:(NSString *)fileName{
NSArray *docs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [docs[0] stringByAppendingPathComponent:fileName];
NSLog(@"path = %@",path);
return [NSURL fileURLWithPath:path];
}
#pragma mark - 實例化錄音機
- (AVAudioRecorder *)recorderWithFileName:(NSString *)fileName{
// 1. 建立URL
NSURL *url = [self urlWithFileName:fileName];
// 2. 實例化錄音機
NSError *error = nil;
AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:url
settings:[self recorderSettings]
error:&error];
if (error) {
NSLog(@"實例化錄音機出錯 - %@", error.localizedDescription);
return nil;
}
// 3. 準備錄音
[recorder prepareToRecord];
return recorder;
}
#pragma mark - 實例化播放器
- (AVAudioPlayer *)playerWithFileName:(NSString *)fileName{
// 1. 建立URL
NSURL *url = [self urlWithFileName:fileName];
// 2. 實例化播放器
NSError *error = nil;
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if (error) {
NSLog(@"實例化播放器出錯 - %@", error.localizedDescription);
return nil;
}
// 3. 準備播放
[player prepareToPlay];
return player;
}
#pragma mark - 啟動時鐘
- (void)startTimer{
NSLog(@"啟動時鐘");
_timer = [NSTimer scheduledTimerWithTimeInterval:0.1f
target:self
selector:@selector(timerFired:)
userInfo:nil
repeats:YES];
}
#pragma mark - 設置錄音機
- (void)setupRecorders{
// 1. 監(jiān)聽器
_monitor = [self recorderWithFileName:kMoniterFile];
// 1.1 設置音量監(jiān)聽
[_monitor setMeteringEnabled:YES];
// 2. 錄音機
_recorder = [self recorderWithFileName:kRecorderFile];
// 2.1 設置代理捡多,監(jiān)聽錄音完成事件
[_recorder setDelegate:self];
// 3. 啟動監(jiān)聽器
[_monitor record];
// 4. 時鐘隨時檢測監(jiān)聽器的數(shù)值
[self startTimer];
}
#pragma mark - 時鐘觸發(fā)方法
- (void)timerFired:(NSTimer *)timer{
// 1. 更新監(jiān)聽器的數(shù)值
[_monitor updateMeters];
// 2. 取出監(jiān)聽器第一個聲道的音量
CGFloat power = [_monitor averagePowerForChannel:0];
// 3. 判斷音量大小
if (power > kRecorderPower) {
// 要錄音蛮穿,首先判斷錄音機是否處于錄音狀態(tài)
if (![_recorder isRecording]) {
NSLog(@"啟動錄音");
// 啟動錄音機
[_recorder record];
}
// 使用當前系統(tǒng)時間,作為末次錄音時間
_lastRecorderTime = [NSDate date];
} else if ([_recorder isRecording]){
NSLog(@"出現(xiàn)靜音...");
// 累計靜音時間钓账,如果過長,停止錄音
if (_silenceDuration > 1.0f) {
NSLog(@"停止錄音絮宁,準備播放");
// 停止錄音
[_recorder stop];
} else {
NSLog(@"累加靜音時長...");
// 累加靜音時間
_silenceDuration += [[timer fireDate] timeIntervalSinceDate:_lastRecorderTime];
}
}
// 4. 如果總靜音時長超過一定時間梆暮,重新啟動監(jiān)聽器
if (_silenceDuration > 10.0f) {
[_monitor stop];
[_monitor record];
}
}
#pragma mark 播放錄音
- (void)startPlaying{
// 1. 實例化播放器
_player = [self playerWithFileName:kRecorderFile];
// 2. 設置播放器屬性
[_player setNumberOfLoops:0];
[_player setDelegate:self];
// 3. 設置播放速度
[_player setEnableRate:YES];
[_player setRate:1.2f];
// 4. 開始播放
[_player play];
}
#pragma mark - 代理方法
#pragma mark - 錄音完成
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
// 1. 停止監(jiān)聽器
[_monitor stop];
// 2. 停止時鐘
[_timer invalidate];
_timer = nil;
// 3. 播放錄音
[self startPlaying];
}
#pragma mark 播放完成
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
// 1. 重新啟動監(jiān)聽器
[_monitor record];
// 2. 啟動時鐘
[self startTimer];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupRecorders];
}
@end