購入した音楽をiTunesで表示すると、明示的な曲が曲のリストの横に赤い明示的なボックスで表示されます。つまり、曲の購入時に表示される明示的なタグは、iTunesライブラリに渡されます。また、クリーンとしてタグ付けされたiTunesの曲についても同じことが行われます。iOSアプリで明示的な曲を特定できるようにしたいのですが、タグが他の曲情報(MPMediaItemProperty)とともにiOSデバイスに渡されるかどうかに関するリソースが見つかりません。取得するには(無限に検索しました!)一部の曲では、タイトルの最後に「[Explicit]」が含まれていますが、これは一部の曲にのみ当てはまり、すべてではありません。タグが存在し、Objectiveから読み取れるかどうかは誰にもわかりません。 -Cコード?
1 に答える
ええと、これを見つけるのに数時間かかりました!を使用するだけでは簡単ではありませんMPMediaQuery
。
概要
必要なデータは、標準チャネル経由では簡単にアクセスできません (つまり、MediaPlayer または AVFoundation フレームワークには、このメタデータにアクセスするための事前定義されたキーはありません)。という名前で、ほとんどの ID3 タグ エディターから利用できますITUNESADVISORY
。このタグは 3 つの値を取ることができます:
0 - アドバイザリ情報なし
1 - 明示的
2 - クリーン
これは私たちが探しているものですが、どのようにアクセスするのでしょうか。フレームワークはかなり高レベルです。MediaPlayer
つまり、アクセス/使用できるデータが限られています。メディア ファイルをより深く調べるには、AVFoundation
フレームワークも使用する必要があります。
方法
どのようなワークフローを使用しているのか正確にはわかりませんが、これをニーズに合わせて調整していただければ幸いです。メディア ファイルが明示的/クリーンかどうかを判断するために、次のようにしました。
MPMediaItem
検査したいファイルを含むを手に入れる必要がありました。を使用してこれをMPMediaPickerController
行い、それを提示し、そのデリゲート メソッドを介して選択したメディア アイテムを取得しました。- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection { // Do whatever is appropriate in your case to extract the media items MPMediaItem* item = [mediaItemCollection.items objectAtIndex:...]; .... }
を取得したら、フレームワークを操作できるように
MPMediaItem
同等のものを取得する必要があります。これを行うには、メディア アイテムの URL パスを使用してアセットを作成します。AVAsset
AVFoundation
MPMediaItem* item = ...; NSURL* path = [item valueForProperty:MPMediaItemPropertyAssetURL]; // We have to check if a path exists, because a media item may not be present on the device. Blame iTunes Match. if (path) { AVAsset* asset = [AVAsset assetWithURL:path]; ....
アセットを取得したら、そこからメタデータを取得する必要があります。実験から、これは iTunes メタデータです。そのため、アセットから抽出してみましょう。
NSArray* metadata = [asset metadataForFormat:AVMetadataFormatiTunesMetadata];
ここから、文書化されていない楽しい作業が始まります。ここで、目的の正しいメタデータ アイテムを見つける必要があります。アドバイザリ キーは、Apple のどのドキュメントでも定数として宣言されていないため、多くの試行錯誤の末、
1920233063
.正しいメタデータ アイテムを取得するには、次のように、メタデータ配列に対してフィルターを実行する必要があります。
NSUInteger advisoryIndex = [metadata indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[AVMetadataItem class]]) { AVMetadataItem* metaItem = (AVMetadataItem*)obj; NSNumber* advisoryKeyTest = @(1920233063); if ([metaItem.key isEqual:advisoryKeyTest]) { *stop = YES; return YES; } return NO; } return NO; }];
それができたら、それが何であるかを判断する必要があります。これは比較的単純で、独自のニーズに合わせて調整できます。曲/メディアのタイプを示す単純な switch ステートメントを作成しました。(注意:メディア ファイルにアドバイザリ タグが含まれていない可能性は十分にあるため、インデックスが存在するかどうかを確認する必要があります)
if (advisoryIndex != NSNotFound) { AVMetadataItem* metaItem = [metadata objectAtIndex:advisoryIndex]; NSInteger advisoryValue = [metaItem.numberValue integerValue]; switch (advisoryValue) { case 0: NSLog(@"%@", @"Unspecified"); break; case 1: NSLog(@"%@", @"Explicit"); break; case 2: NSLog(@"%@", @"Clean"); break; default: NSLog(@"%@", @"Unexpected Value"); break; } }
結論
これで、歌がクリーンか露骨か、またはどちらでもないかを判断する方法がわかりました。これはアドバイザリ データを見つけるために静的な数値を使用しており、Apple のヘッダーで定義されている定数にはリンクされていないため、これが過去、現在、および将来のすべての iOS バージョンで機能することを保証できません。これを iOS 6 でテストしたところ、問題ないようでした。マイレージは異なる場合があります。
残念なことに、Apple はすぐにこの機能を提供していません (アドバイザリ キーを提供しただけでも)。必要に応じて、この機能をカテゴリ内に配置できます。