Extracting ID3 tags from MP3 over HTTP Live Stream

2020-02-23 08:55发布

问题:

I've been having quite a difficult time extracting ID3 information from an MP3 being streamed over Live HTTP Streaming (using the Wowza media server, if anyone is curious). I know that the tags (right now the album tag and the album artwork tag) are being properly embedded in each of the file segments because when I download them manually I can see them in each segment as listed in the .m3u index file generated by the server.

I am using the AVFoundation classes to do this, and I have it setup as such:

- (void)initializeAudioStream {
    NSURL *streamUrl = [NSURL URLWithString:self.urlField.text];
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:streamUrl];
    self.musicPlayer = [AVPlayer playerWithPlayerItem:playerItem];
    self.musicPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
    [self.musicPlayer addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:NULL];
}

Once my KVO method is triggered, I start playing self.musicPlayer and I call addPeriodicTimeObserverForInterval on it for each 1/4 second. It is in this method that I try to extract the ID3 metadata.

I have tried everything I can think of on the iOS side of things to accomplish this, including printing out

self.musicPlayer.currentItem.asset.commonMetadata

as well as iterating over each of the AVAssetTrack instances and printing out their metadata.

for (AVAssetTrack *track in self.musicPlayer.currentItem.asset.tracks) {
    NSLog(@"Media type of track: %@", track.mediaType);
    NSLog(@"Track metadata: %@", track.commonMetadata);
}

What's interesting is that the asset always says it has 2 tracks. When I print out their mediaType property I get "soun" for the first one and "tmet" for the second. My assumption is that the first track is the audio data itself and the second track is metadata. However, I only ever see an empty array in commonMetadata.

I also check the status of the properties using statusOfValueForKey:error on the tracks, and the commonMetadata key always comes back as AVKeyValueStatusLoaded.

Any ideas? I'm at a complete loss here.

Also, I am currently running this through the iPhone 4 simulator running iOS 4.2.1. I can't yet put it on a device since Apple is still approving my company's developer account.

回答1:

Instead of using commonMetadata you might want to try using timedMetadata on the AVPlayerItem:

[playerItem addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionNew context:NULL];


回答2:

Just an idea: using fiddler/othersniffer to sniff the http request content to see if metadata is present ?



回答3:

You need to register a subclass of NSURLProtocol in Appdelegate didFinishLaunchingWithOptions method.

then you can see the response of the request made by your video player