AVFoundation開發秘籍筆記-03資源和元數據

一、資源AVAsset

AVAsset是一個抽象類和不可變類,定義媒體資源混合呈現的方式,將媒體資源的靜態屬性模塊化成為一個整體,比如標題、時長和元數據等。

AVAsset不需要考慮媒體資源所具有的兩個重要范疇:1、提供了對基本媒體格式的層抽象,不需要關注具體格式,只關注資源這個概念。2、隱藏資源的位置信息。

AVAsset本身不是媒體資源,但他可以作為時基媒體的容器,由一個或多個帶有描述自身元數據的媒體組成。

AVAssetTrack類代表保存在資源的統一類型媒體,并對每個資源建立相應的模型。

資源的曲目可以通過tracks屬性進行訪問。

二、創建資源

為現有媒體資源創建AVAsset對象時,可以通過URL對齊進行初始化來實現,可以是本地文件URL,也可以是遠程資源的URL

NSString *path = @"";
NSURL *fileUrl = [NSURL fileURLWithPath:path];
NSDictionary *dict = @{AVURLAssetPreferPreciseDurationAndTimingKey : @YES};
    AVAsset *asset = [AVAsset assetWithURL:fileUrl];

AVAsset是一個抽象類,意味著它不能直接被實例化,使用assetWithURL創建實例時,實際上是創建了他子類AVURLAsset的一個實例。一般會直接創建這個類,因為可以通過傳遞選項字典來調整資源的創建方式。

NSURL *fileUrl;
NSDictionary *dict = @{AVURLAssetPreferPreciseDurationAndTimingKey : @YES}; 
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:fileUrl options:dict];

AVURLAssetPreferPreciseDurationAndTimingKey這個布爾值支出這個asset是否應該準備標出一個準確的時間和提供一個以時間為種子的隨機存取。

只是播放asset,options傳遞nil,或者字典里對應的值是NO(包含在NSValue對象中)

給asset添加一個composition,需要精確的隨機存取,傳遞一個字典,對應值是YES(包含在NSValue對象中)

1、iOS Assets庫

用戶使用系統子弟的Camera程序或者第三方視頻捕捉程序捕捉的侍寢,通常先保存在用戶照片庫中。iOS提供的Assets庫可以實現從照片庫這種讀寫的功能。 iOS9.0以后,<AssetsLibrary/AssetsLibrary.h>被取消。

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    [group setAssetsFilter:[ALAssetsFilter allVideos]];
    NSLog(@"bbb");
    if ([group numberOfAssets] > 0) {
        [group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:0] options:0 usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
            if (result) {
                id representation = [result defaultRepresentation];
                NSURL *url = [representation url];
                AVAsset *asset = [AVAsset assetWithURL:url];
                
            }
        }];
    }
    
    
} failureBlock:^(NSError *error) {
    
}];

2、iOS iPod庫

iPod Library歌曲(也稱作本地音樂庫歌曲)也就是用戶從iTunes中導入的歌曲。MediaPlayer框架提供了API,實現在這個庫中查詢和獲取條目。當需要的條目找到后可以獲取其URL并使用這個URL初始化一個資源:

MediaPlayer框架提供了一個名為MPMediaPropertyPredicate的類,它用于構建幫助用戶在iPod苦衷查找具體內容所用的查詢語句。需要導入庫文件<MediaPlayer/MediaPlayer.h>.

MPMediaPropertyPredicate *artistPredicate = [MPMediaPropertyPredicate predicateWithValue:@"劉德華" forProperty:MPMediaItemPropertyArtist];
MPMediaPropertyPredicate *albumPredicate = [MPMediaPropertyPredicate predicateWithValue:@"真永遠" forProperty:MPMediaItemPropertyArtist];
MPMediaPropertyPredicate *songPredicate = [MPMediaPropertyPredicate predicateWithValue:@"今天" forProperty:MPMediaItemPropertyArtist];
MPMediaQuery *query = [[MPMediaQuery alloc] init];
[query addFilterPredicate:artistPredicate];
[query addFilterPredicate:albumPredicate];
[query addFilterPredicate:songPredicate];
NSArray *results = [query items];
if (results.count > 0) {
    MPMediaItem *item = results[0];
    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    AVAsset *asset = [AVAsset assetWithURL:assetURL];
    
}

三、異步載入

AVAsset使用一種高效的設計方法,即延遲載入資源的睡醒,知道請求時才載入。這樣可以快速創建資源,而不用考慮因為立即載入相關媒體或元數據所帶來的問題。有一點,屬性的訪問總是同步發生的,如果正在請求的屬性沒有預先載入,程序就會阻塞,知道可以做出適當的響應。要解決這個問題,應該使用異步的方法來查詢資源的屬性。

AVAssetAVAssetTrack都采用了AVAsynchornousKeyValueLoading協議,該協議通過下面給出的方法實現了一步查詢屬性的功能:

NSURL *assetUrl = [[NSBundle mainBundle] URLForResource:@"崔健-假行僧" withExtension:@"mp3"];
AVAsset *asset = [AVAsset assetWithURL:assetUrl];
    
NSArray *keys = @[@"tracks"];
    
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
    NSError *error;
    
    AVKeyValueStatus status = [asset statusOfValueForKey:@"tracks" error:&error];
    switch (status) {
        case AVKeyValueStatusLoaded:
            //已經加載,繼續處理
            NSLog(@"loaded");
            NSLog(@"%@",asset.tracks);
            break;
        case AVKeyValueStatusFailed:
            NSLog(@"failure");
            break;
        case AVKeyValueStatusCancelled:
            NSLog(@"canceld");
            break;
        case AVKeyValueStatusUnknown:
            NSLog(@"unknown");
            break;
            
        default:
            NSLog(@"default");
            break;
    }
}];

可使用statusOfValueForKey: error:方法查詢一個給定屬性的狀態,該方法會返回一個枚舉類型的AVKeyValueStatus值,用于表示當前所請求的屬性的狀態。如果狀態不是AVKeyValueStatusLoaded,意味著此時請求該屬性可能導致程序卡杜,需要異步載入一個給定的屬性,可以調用loadValuesAsynchronouslyForKeys: completionHandler:方法,為其提供一個具有一個或多個key的數組(資源的屬性名)和一個completionHandler塊,當資源處于回應請求狀態時,就會回調這個塊方法。

注意:

  • completionHandler可能會在任意一個隊列中被調用,在對用戶界面做出相應更新之前,必須先回到主隊列中。

  • 在請求多個屬性時,每次調用loadValuesAsynchronouslyForKeys: completionHandler:方法只會調用一次completionHandler,調用該方法的次數并不是根據傳遞給這個方法的鍵的個數決定的。

  • 需要為每個請求的屬性調用statusOfValueForKey: error:不能假設所有屬性都返回相同的狀態值。

四、媒體元數據

對于元數據的使用有一定的挑戰,每個媒體類型就具有唯一的格式,并且通常要求開發者對相應格式讀寫操作的底層技術有所了解。

AVFoundation提供一套統一的方法,用來處理媒體元數據,可以讓開發者不需要考慮大多數特定格式的細節。

1、元數據格式

Apple環境下遇到的媒體類型主要有4種,分別是:QuickTime(mov)、MPEG-4 video(mp4或m4v)、MPEG-4 Audio(m4a)、MPEG-Layer III audio(mp3)。

  • QuickTime

  • MPEG-4音頻和視頻

  • MP3

五、使用元數據

AVAssetAVAssetTrack都可以實現查詢相關元數據的功能,大部分情況使用AVAsset提供的元數據,不過涉及獲取曲目一級元數據等情況時會使用AVAssetTrack

讀取具體資源元數據的接口由AVMetadataItem提供。提供一個面向對象的接口,可以對存儲于QuickTime、MPEG-4 atom和ID3幀中的元素進行訪問。

  • 鍵空間(key spaces): AV中使用鍵空間作為將相關鍵組合在一起的方法,可以實現對AVMetadataItem實例集合的篩選,每個資源至少包含兩個鍵空間,供從中獲取元數據。

common鍵空間用來定義所有支持的媒體類型的鍵,包括諸如曲名、歌手和插圖信息等常見元素。可以通過查詢資源或曲目的[asset commonMetadata]屬性從common鍵空間獲取與數據,這個屬性會返回一個包含所有可用元數據的數據.

metadataForFormat:訪問指定格式的元數據格式,返回一個包含所有相關元數據信息的NSArray。

[asset availableMetadataFormats]返回資源中包含的所有元數據格式

1、查找元數據

2、使用AVMetadataItem

AVMetadataItem最基本的形式是一個封裝鍵值對的封裝器。而已通過它查詢key或commonKey。value屬性被定義成id<NSObject,NSCopying>形式,AVMetadataItem還提供了三個類型強制屬性stringValuenumberValuedataValue,如果已經提前知道value類型,可以強制轉換。

NSURL *assetUrl = [[NSBundle mainBundle] URLForResource:@"今天" withExtension:@"mp3"];
AVAsset *asset = [AVAsset assetWithURL:assetUrl];

for (AVMetadataFormat item in [asset availableMetadataFormats]) {
    NSArray *medata = [asset metadataForFormat:item];
    for (AVMetadataItem *mitem in medata) {
        NSLog(@"%@:%@",mitem.key,mitem.value);
    }
}

//    TPE1:劉德華
//    TALB:真永遠
//    TIT2:今天
//    TYER:1995-08-01

六、創建MetaManager應用程序

七、保存元數據

AVAsset是一個不可變類,如果要保存元數據的修改,使用AVAssetExportSession導出一個新的資源副本以及元數據改動。

AVAssetExportSession用于將AVAsset內容根據導出預設條件進行轉碼,并將導出資源寫到磁盤。它提供了多個功能來實現將一種格式轉換為另一種格式、修訂資源的內容、修改資源的音頻和視頻行為、寫入新的元數據。

創建一個AVAssetExportSession實例需要提供資源和導出預設。導出預設用于確定導出內容的質量、大小等屬性。創建導出會話后,還要指定導出內容地址outputURL,并且給出一個outputFileType表示要導出的格式。最后調用exportAsynchronouslyWithCompletionHandler:開始導出。

NSString *presetName = AVAssetExportPresetPassthrough;
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:self.asset presetName:presetName];
    
NSURL *outputUrl ;
    
exportSession.outputURL = outputUrl;
exportSession.outputFileType = @"";
//    exportSession.metadata = [_asset availableMetadataFormats]
    
[exportSession exportAsynchronouslyWithCompletionHandler:^{
    AVAssetExportSessionStatus status = exportSession.status;
    BOOL success = (status == AVAssetExportSessionStatusCompleted);
    if (success) {
        
    }
    
}];
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容