iOS從零開始學習直播之音頻1.播放本地音頻文件

来源:http://www.cnblogs.com/doujiangyoutiao/archive/2016/11/24/6098367.html
-Advertisement-
Play Games

  現在直播越來越火,儼然已經成為了下一個紅海。作為一個資深碼農(我只喜歡這樣稱呼自己,不喜歡別人這樣稱呼我),我必須趕上時代的潮流,開始研究視頻直播。發現視屏直播類的文章上來就講拉流、推流、採集、美顏等第三方類的使用,我是小白很不懂啊。所以我決定開始系統分享從音頻、視頻類到視頻 ...


  現在直播越來越火,儼然已經成為了下一個紅海。作為一個資深碼農(我只喜歡這樣稱呼自己,不喜歡別人這樣稱呼我),我必須趕上時代的潮流,開始研究視頻直播。發現視屏直播類的文章上來就講拉流、推流、採集、美顏等第三方類的使用,我是小白很不懂啊。所以我決定開始系統分享從音頻、視頻類到視頻直播的相關知識,也算溫故知新吧。我覺得去面試,說我會用第三方庫和懂第三方庫的原理,肯定是面試官對後者更有興趣吧。
  先從音頻講起,本篇文章主要講播放本地視頻。

(一)準備工作

1.導入AVFoundation框架
2.工程導入一個音頻文件,向拖圖片一樣導入工程里。

#import "FHAudioViewController.h"
#import <AVFoundation/AVFoundation.h>

#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height

@interface FHAudioViewController ()<AVAudioPlayerDelegate>{
    
    AVAudioPlayer *_avAudioPlayer; // 播放器palyer
    UISlider *_pregressSlider; // 播放進度
    UILabel *_pregressLabel; // 進度
    UISlider *_volumeSlider;   // 聲音控制
    NSTimer *_timer; // 監控音頻播放進度
}
@end

@implementation FHAudioViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1.初識化UI
    // (1)初始化三個Button;
    NSArray *titleArr = @[@"播放",@"暫停",@"停止"];
    for (int i = 0; i < titleArr.count; i++ ) {
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        [self.view addSubview:button];
        [button setFrame:CGRectMake(20 + i * 50, 130 , 60, 40)];
        [button setTitle:titleArr[i] forState:UIControlStateNormal];
         button.tag = i+100;
        [button addTarget:self action:@selector(controlAVAudioAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    
    // (2)初始化進度條
    _pregressSlider = [[UISlider alloc] initWithFrame:CGRectMake(20, 50, ScreenWidth - 130 - 20, 20)];
    [self.view addSubview: _pregressSlider];
    _pregressSlider.minimumValue = 0.0f;
    _pregressSlider.maximumValue = 1.0f;
    [_pregressSlider addTarget:self action:@selector(pregressChange) forControlEvents:UIControlEventValueChanged];
    _pregressLabel = [[UILabel alloc] initWithFrame:CGRectMake(ScreenWidth - 120, 50, 100, 20)];
    _pregressLabel.text = @"00:00/00:00";
    [self.view addSubview:_pregressLabel];
    
    // (3)用NSTimer來監控音頻播放進度
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(playProgress) userInfo:nil repeats:YES];
    
    // (4)初始化音量
    _volumeSlider = [[UISlider alloc] initWithFrame:CGRectMake(20, 90, ScreenWidth - 130 - 20, 20)];
    [_volumeSlider addTarget:self action:@selector(volumeChange) forControlEvents:UIControlEventValueChanged];
    _volumeSlider.minimumValue = 0.0f;
    _volumeSlider.maximumValue = 10.0f;
    _volumeSlider.value = 1.0f;
    [self.view addSubview:_volumeSlider];
    UILabel *volumeLabel = [[UILabel alloc] initWithFrame:CGRectMake(ScreenWidth - 120, 90, 40, 20)];
    volumeLabel.text = @"音量";
    [self.view addSubview:volumeLabel];
    
    // 2.播放本地音頻文件
    // (1)從boudle路徑下讀取音頻文件 陳小春 - 獨家記憶文件名,mp3文件格式
    NSString *path = [[NSBundle mainBundle] pathForResource:@"陳小春 - 獨家記憶" ofType:@"mp3"];
    // (2)把音頻文件轉化成url格式
    NSURL *url = [NSURL fileURLWithPath:path];
    // (3)初始化音頻類 並且添加播放文件
    _avAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    // (4) 設置代理
    _avAudioPlayer.delegate = self;
    // (5) 設置初始音量大小 預設1,取值範圍 0~1
    _avAudioPlayer.volume = 1;
    // (6)設置音樂播放次數 負數為一直迴圈,直到stop,0為一次,1為2次,以此類推
    _avAudioPlayer.numberOfLoops = 0;
    // (5)準備播放
    [_avAudioPlayer prepareToPlay];
}

效果

分析:用兩個Slider來分別表示和控制播放進程和音量。三個按鈕分別表示播放、暫停、控制。用NSTimer來每0.01秒改變一次播放進度。

(二)自定義方法

// 音頻控制
- (void)controlAVAudioAction : (UIButton *)button {
    
    NSInteger tag = button.tag;
    
    // 播放
    if (tag == 100) {
        
        [_avAudioPlayer play];
    }
    
    // 暫停
    if (tag == 101) {
        
        [_avAudioPlayer pause];
    }
    
    // 停止
    if (tag == 102) {
        
        _avAudioPlayer.currentTime = 0;
        [_avAudioPlayer stop];
    }
}
// 播放進度控制
- (void)pregressChange{
    
    _avAudioPlayer.currentTime = _pregressSlider.value * _avAudioPlayer.duration;
}
// 播放進度條
- (void)playProgress {
    // 更改當前播放時間
    NSString *currentMStr = [self FormatTime:_avAudioPlayer.currentTime / 60];
    NSString *currentSStr = [self FormatTime:(int)_avAudioPlayer.currentTime % 60];
    NSString *durationMStr = [self FormatTime:_avAudioPlayer.duration / 60];
    NSString *durationSStr = [self FormatTime:(int)_avAudioPlayer.duration % 60];
    _pregressLabel.text = [NSString stringWithFormat:@"%@:%@/%@:%@",currentMStr,currentSStr,durationMStr,durationSStr];
   // 播放進度條
_pregressSlider.value = _avAudioPlayer.currentTime / _avAudioPlayer.duration;
}
- (NSString *)FormatTime: (int)time {
    
    if (time < 10) {
        return  [NSString stringWithFormat:@"0%d",time];
    }else {
        return  [NSString stringWithFormat:@"%d",time];
    }
}
// 音量控制
- (void)volumeChange {
    _avAudioPlayer.volume = _volumeSlider.value;
}

分析:我主要說一下音量,其他的方法寫的都很清楚了。音量這個比較特殊。_avAudioPlayer.volume = 1;這個值是百分比,設置的就是視頻播放器音量是系統音量的百分之多少。好比說系統音量是0.5,這個值設置成0.6,此時音頻播放器的音量也就是你聽到的音量相當於系統音量的0.3;這裡系統音量指:

那個中間喇叭的音量。它的取值範圍也是0~1;

// 獲取當前系統音量
- (float)getCurrentDeviceVolumu {
    
   float volume = [[AVAudioSession sharedInstance] outputVolume];     NSLog(@"getCurrentDeviceVolumu = %f",volume);
    
    return volume;
}

(三)AVAudioPlayerDelegate

// 當播放完成時執行的代理
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    
    NSLog(@"audioPlayerDidFinishPlaying");
    _timer = nil;
    [_timer invalidate];
}
// 當播放發生錯誤時調用
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error {
    NSLog(@"播放發生錯誤%@",error);
}
// 當播放器發生中斷時調用 如來電
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player {
    
    NSLog(@"audioPlayerBeginInterruption");
    // 暫停播放 用戶不暫停,系統也會幫你暫停。但是如果你暫停了,等來電結束,需要再開啟
    [_avAudioPlayer pause];
}
// 當中斷停止時調用 如來電結束
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags {
    
    NSLog(@"audioPlayerEndInterruption");
    // 你可以幫用戶開啟 也可以什麼都不執行,讓用戶自己決定
    [_avAudioPlayer play];
}

  本工程將放到本人的GitUp上,歡迎下載。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 看效果:Html: CSS: jQuery: 或者使用連寫法: ...
  • ...
  • 通過js實現DropDownList下拉框可以直接輸入信息也可以直接選擇 ...
  • 在Android開發中,我們經常會需要在Android界面上彈出一些對話框,比如詢問用戶或者讓用戶選擇。這些功能我們叫它Android Dialog對話框,AlertDialog實現方法為建造者模式。下麵我們簡單模擬一個挑媳婦的選擇確定對話框(單選)對話框,不同於示例二之處在於本次只要不確定就可以後 ...
  • 首先打開終端(在搜索裡面搜索Te即可出來) 然後輸入 cd /Library/Java/Home/bin/ 然後這步很關鍵,由於我們用的是當前用戶,所以沒有最高許可權,不能在Library文件夾下生成任何文件,所以照抄網上的方法是無法創建成功的,複製粘貼步驟4的內容。 keytool -genkey ...
  • 在Android開發中,我們經常會需要在Android界面上彈出一些對話框,比如詢問用戶或者讓用戶選擇。這些功能我們叫它Android Dialog對話框,AlertDialog實現方法為建造者模式。下麵我們簡單模擬一個選花魁的簡單普通選項(單選)對話框,如下圖: Layout界面代碼: Java功 ...
  • 一、ListView的理解 1.什麼ListView? 一種用來顯示多個可滑動項(Item)列表的的ViewGroup 需要使用Adapter將集合數據和每一個Item所對應的佈局動態適配到ListView中顯示 顯示列表: listView.setAdapter(adapter) 更新列表: ad ...
  • 前言 學習本系列內容需要具備一定 HTML 開發基礎,沒有基礎的朋友可以先轉至 "HTML快速入門(一)" 學習 本人接觸 React Native 時間並不是特別長,所以對其中的內容和性質瞭解可能會有所偏差,在學習中如果有錯會及時修改內容,也歡迎萬能的朋友們批評指出,謝謝 文章第一版出自簡書,如果 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...