English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Example explanation of the usage of iOS music player DOUAudioStreamer

Es ist schon lange her, dass ich etwas geschrieben habe. In letzter Zeit habe ich so viel Überstunden gemacht, dass ich heute die Gelegenheit genutzt habe, den von mir verwendeten Musikplayer DOUAudioStreamer zu organisieren. Da das Projekt zuvor AVPlayer verwendet hat, ist das auch in Ordnung, aber es muss erst eine Weile gecacht werden, bevor es abgespielt wird. Nachdem der Chef das gesehen hat, hat er verlangt, dass das Caching während des Abspiels geändert wird (wenn es ein Netzwerk gibt, wird auf den Wiedergabeknopf geklickt und es wird sofort abgespielt), warum hat er das nicht früher gesagt! Warum hat er das nicht früher gesagt! Warum hat er das nicht früher gesagt! Was kann man noch tun? Man kann ihn nur vergeben und weiter mit dem Code schreiben。。。。。。(Also, hier ist der Code)

Eins. Importieren Sie die Drittanbieter-Bibliothek

pod 'DOUAudioStreamer'

oder GitHup-Download-Adresse:https://github.com/douban/DOUAudioStreamer

Zwei. Verwenden

1.Laden Sie die Datei NAKPlaybackIndicatorView und die Headerdateien MusicIndicator.h und MusicIndicator.m aus dem Demo und importieren Sie die Headerdateien

//Musikwiedergabe
#import "DOUAudioStreamer.h"
#import "NAKPlaybackIndicatorView.h"
#import "MusicIndicator.h"
#import "Track.h"

Wie im Bild gezeigt:

2.Erstellen Sie eine Track-Klasse, um die URLs der Musikwiedergabe zu speichern

3.Fügen Sie in der .h-Datei, die die benötigten Oberflächen enthält, DOUAudioStreamer hinzu und initialisieren Sie ihn als Singleton

+ (instancetype)sharedInstance ;
@property (nonatomic, strong) DOUAudioStreamer *streamer;

 

Wie im Bild gezeigt:

In der .m-Datei implementieren:

static void *kStatusKVOKey = &kStatusKVOKey;
static void *kDurationKVOKey = &kDurationKVOKey;
static void *kBufferingRatioKVOKey = &kBufferingRatioKVOKey;
@property (strong, nonatomic) MusicIndicator *musicIndicator;
@property (nonatomic, strong) Track *audioTrack;
+ (instancetype)sharedInstance {
 static HYNEntertainmentController *_sharedMusicVC = nil;
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
  _sharedMusicVC = [[HYNEntertainmentController alloc] init];
  _sharedMusicVC.streamer = [[DOUAudioStreamer alloc] init];
 }); 
 return _sharedMusicVC;
}

 

Knopfevent ausführen

#pragma mark ---Musikwiedergabeknopf
-(void)playMusicStart:(UIButton *)sender
{
  //Zellen durch Button erhalten
  MusicCollectionViewCell *musicCell = (MusicCollectionViewCell *)[[sender superview] superview];
 if(_playFirst == 0){//_playFirst == 0 für erstes Abspielen, anderes für Pausieren
  NSURL *url = [NSURL URLWithString:HttpImgUrl(musicCell.model.musicUrl)];
  _audioTrack.audioFileURL = url;
  @try {
   [self removeStreamerObserver];
  } 
  }
  //Bevor DOUAudioStreamer wiedergibt, muss es auf nil gesetzt werden
  _streamer = nil;
  _streamer = [DOUAudioStreamer streamerWithAudioFile:_audioTrack];
  [self addStreamerObserver];
  [_streamer play];
 }
 if([_streamer status] == DOUAudioStreamerPaused ||
  [_streamer status] == DOUAudioStreamerIdle)
  [sender setBackgroundImage:[UIImage imageNamed:@"music_play_icon"] forState:UIControlStateNormal];
  [_streamer play]; 
 } else {
  [sender setBackgroundImage:[UIImage imageNamed:@"music_stop_icon"] forState:UIControlStateNormal];
  [_streamer pause]; 
 }
 _playFirst++;
}

 

Zuhören hinzufügen

- (void)addStreamerObserver {
 _streamer.addObserver(self, forKeyPath:@"status", options:NSKeyValueObservingOptionNew, context:kStatusKVOKey);
 [_streamer addObserver:self forKeyPath:@"duration" options:NSKeyValueObservingOptionNew context:kDurationKVOKey];
 [_streamer addObserver:self forKeyPath:@"bufferingRatio" options:NSKeyValueObservingOptionNew context:kBufferingRatioKVOKey]; 
}
/// Player destroyed
- (void)dealloc{
 if (_streamer !=nil) {
  [_streamer pause];
  [_streamer removeObserver:self forKeyPath:@"status" context:kStatusKVOKey];
  [_streamer removeObserver:self forKeyPath:@"duration" context:kDurationKVOKey];
  [_streamer removeObserver:self forKeyPath:@"bufferingRatio" context:kBufferingRatioKVOKey];
  _streamer =nil;
 } 
}
- (void)removeStreamerObserver {
 [_streamer removeObserver:self forKeyPath:@"status"];
 [_streamer removeObserver:self forKeyPath:@"duration"];
 [_streamer removeObserver:self forKeyPath:@"bufferingRatio"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
 if (context == kStatusKVOKey) {
  [self performSelector:@selector(updateStatus)]
      onThread:[NSThread mainThread]
     withObject:nil
    waitUntilDone:NO];
 } else if (context == kDurationKVOKey) {
  [self performSelector:@selector(updateSliderValue:)
      onThread:[NSThread mainThread]
     withObject:nil
    waitUntilDone:NO];
 } else if (context == kBufferingRatioKVOKey) {
  [self performSelector:@selector(updateBufferingStatus)
      onThread:[NSThread mainThread]
     withObject:nil
    waitUntilDone:NO];
 } else {
  [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
 }
}
- (void)updateSliderValue:(id)timer {
}
-(void)updateBufferingStatus
{ 
}
- (void)updateStatus {
 //self.musicIsPlaying = NO;
 _musicIndicator.state = NAKPlaybackIndicatorViewStateStopped;
 switch ([_streamer status]) {
  case DOUAudioStreamerPlaying:
   // self.musicIsPlaying = YES;
   _musicIndicator.state = NAKPlaybackIndicatorViewStatePlaying;
   break;
  case DOUAudioStreamerPaused:
   break;
  case DOUAudioStreamerIdle:
   break;
  case DOUAudioStreamerFinished:
   break;
  case DOUAudioStreamerBuffering:
   _musicIndicator.state = NAKPlaybackIndicatorViewStatePlaying;
   break;  
  case DOUAudioStreamerError:
   break;
 } 
}

Dadurch kann wiedergegeben werden.

Die Musikanzeige im Sperrbildschirm, die Wiedergabe wird angehalten, wenn das Headset herausgezogen wird, und die Audiodurchbruchereignisse werden überwacht

-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//Akzeptieren Sie Remotecontrol
[self becomeFirstResponder];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
//Dies darf nicht vergessen werden
-(BOOL)canBecomeFirstResponder{
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
//Musikspieler
[self initPlayer];
}
#pragma mark =========================Musikwiedergabe==============================
//Musikspieler
-(void)initPlayer
{
_audioTrack = [[Track alloc] init];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
//Lassen Sie die App Remotecontrolereignisse akzeptieren
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
//Fügen Sie Benachrichtigungen hinzu, um die Wiedergabe nach dem Ausstecken des Headsets zu pausieren
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:nil];
// Überwachen Sie Audiodurchbruchsereignisse
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionWasInterrupted:) name:AVAudioSessionInterruptionNotification object:session];
}
// Überwachen Sie Audiodurchbruchsereignisse
- (void)audioSessionWasInterrupted:(NSNotification *)notification
{
 //Wenn unterbrochen
if (AVAudioSessionInterruptionTypeBegan == [notification.userInfo[AVAudioSessionInterruptionTypeKey] intValue])
{
[_streamer pause];
UIButton *btn = (UIButton *)[self.view viewWithTag:2000];
[btn setBackgroundImage:[UIImage imageNamed:@"music_stop_icon"] forState:UIControlStateNormal];
}
else if (AVAudioSessionInterruptionTypeEnded == [notification.userInfo[AVAudioSessionInterruptionTypeKey] intValue])}}
{
}
}
// Nach dem Ausziehen der Kopfhörer die Wiedergabe pausieren
-(void)routeChange:(NSNotification *)notification{
NSDictionary *dic=notification.userInfo;
int changeReason= [dic[AVAudioSessionRouteChangeReasonKey] intValue];
//Gleich AVAudioSessionRouteChangeReasonOldDeviceUnavailable bedeutet, dass der alte Ausgang nicht verfügbar ist
if (changeReason==AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
AVAudioSessionRouteDescription *routeDescription=dic[AVAudioSessionRouteChangePreviousRouteKey];
AVAudioSessionPortDescription *portDescription= [routeDescription.outputs firstObject];
//Das ursprüngliche Gerät sind Kopfhörer, dann pausieren
if ([portDescription.portType isEqualToString:@"Headphones"]) {
[_streamer pause];
UIButton *btn = (UIButton *)[self.view viewWithTag:2000];
[btn setBackgroundImage:[UIImage imageNamed:@"music_stop_icon"] forState:UIControlStateNormal];
}
}
}
//Musikdisplay beim Sperrbildschirm (dieser Methodenaufruf kann bei einem Klick auf Wiedergabe erfolgen, um Werte zu übergeben)
- (void)setupLockScreenInfoMitSing:(NSString *)sign MitSigner:(NSString *)signer MitImage:(UIImage *)image
{
// 1.erhalten Sie den Sperrbildschirm-Zentralen
MPNowPlayingInfoCenter *playingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
//Initialize a dictionary to store music information
NSMutableDictionary *playingInfoDict = [NSMutableDictionary dictionary];
// 2Set the song name
if (sign) {
[playingInfoDict setObject:sign forKey:MPMediaItemPropertyAlbumTitle];
}
// Set the artist name
if (signer) {
[playingInfoDict setObject:signer forKey:MPMediaItemPropertyArtist];
}
// 3Set the cover image
//UIImage *image = [self getMusicImageWithMusicId:self.currentModel];
if (image) {
MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:image];
[playingInfoDict setObject:artwork forKey:MPMediaItemPropertyArtwork];
}
// 4Set the total duration of the song
//[playingInfoDict setObject:self.currentModel.detailDuration forKey:MPMediaItemPropertyPlaybackDuration];
//Assign music information to the nowPlayingInfo property of the lock screen center
playingInfoCenter.nowPlayingInfo = playingInfoDict;
// 5.Enable remote interaction
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
//Lockscreen operation
- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
UIButton *sender = (UIButton *)[self.view viewWithTag:2000];
switch (receivedEvent.subtype) {//Überprüfen Sie, ob es sich um eine Remote-Control handelt
case UIEventSubtypeRemoteControlPause:
[[HYNEntertainmentController sharedInstance].streamer pause];
[sender setBackgroundImage:[UIImage imageNamed:@"music_stop_icon"] forState:UIControlStateNormal];
break;
case UIEventSubtypeRemoteControlStop:
break;
case UIEventSubtypeRemoteControlPlay:
[[HYNEntertainmentController sharedInstance].streamer play];
[sender setBackgroundImage:[UIImage imageNamed:@"music_play_icon"] forState:UIControlStateNormal];
break;
case UIEventSubtypeRemoteControlTogglePlayPause:
break;
case UIEventSubtypeRemoteControlNextTrack:
break;
case UIEventSubtypeRemoteControlPreviousTrack:
break;
default:
break;
}
}
}

Gesamtbild:

Das obige Bild zeigt den ungespielten Zustand

Das obige Bild zeigt den Wiedergabeprozess

Das obige Bild zeigt den Bildschirmschoner

Es sollte nichts hinzuzufügen geben, für den Moment ist es genug, bei Unzulänglichkeiten kann in der folgenden Kommentarsektion diskutiert werden, vielen Dank für die Unterstützung von呐喊教程。

You may also like