2012-03-06 5 views
17

Я создаю MP3-плеер для iOS, который воспроизводит аудиофайлы, размещенные в Интернете. Я хочу предложить возможность играть в файлы в автономном режиме, поэтому я загружаю файлы с помощью ASIHTTP, но я не могу найти информацию об инициализации AVPlayer с помощью mp3 в каталоге документов приложения. Кто-нибудь делал это раньше? Возможно ли это?AVPlayer и локальные файлы

* Я разместил ответ ниже, в котором показано, как использовать IOS AvPlayer для локальных и http-файлов. Надеюсь это поможет!

+0

Рассматривали вы с помощью внутреннего SQLite вместо документов реж? – rwyland

ответ

31

я решил ответить на мой собственный вопрос, потому что я чувствовал, что там очень мало документации о том, как использовать Apple, при условии, AVPlayer как местных, так и поток (через HTTP) файлов. Чтобы помочь понять решение, я собрал sample project on GitHub in Objective-C и Swift. Код ниже - Objective-C, но вы можете загрузить мой пример Swift, чтобы увидеть это. Это очень похоже!

Я обнаружил, что два способа настройки файлов почти идентичны, за исключением того, как вы создаете экземпляр вашего NSURL для Asset> PlayerItem> AVPlayer.

Вот набросок основных методов

.h файл (частичный код)

-(IBAction) BtnGoClick:(id)sender; 
-(IBAction) BtnGoLocalClick:(id)sender; 
-(IBAction) BtnPlay:(id)sender; 
-(IBAction) BtnPause:(id)sender; 
-(void) setupAVPlayerForURL: (NSURL*) url; 

.m файл (частичный код)

-(IBAction) BtnGoClick:(id)sender { 

    NSURL *url = [[NSURL alloc] initWithString:@""]; 

    [self setupAVPlayerForURL:url]; 
} 

-(IBAction) BtnGoLocalClick:(id)sender { 

    // - - - Pull media from documents folder 

    //NSString* saveFileName = @"MyAudio.mp3"; 
    //NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    //NSString *documentsDirectory = [paths objectAtIndex:0]; 
    //NSString *path = [documentsDirectory stringByAppendingPathComponent:saveFileName]; 

    // - - - 

    // - - - Pull media from resources folder 

    NSString *path = [[NSBundle mainBundle] pathForResource:@"MyAudio" ofType:@"mp3"]; 

    // - - - 

    NSURL *url = [[NSURL alloc] initFileURLWithPath: path]; 

    [self setupAVPlayerForURL:url]; 
} 

-(void) setupAVPlayerForURL: (NSURL*) url { 
    AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; 
    AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset]; 

    player = [AVPlayer playerWithPlayerItem:anItem]; 
    [player addObserver:self forKeyPath:@"status" options:0 context:nil]; 
} 


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 

    if (object == player && [keyPath isEqualToString:@"status"]) { 
     if (player.status == AVPlayerStatusFailed) { 
      NSLog(@"AVPlayer Failed"); 
     } else if (player.status == AVPlayerStatusReadyToPlay) { 
      NSLog(@"AVPlayer Ready to Play"); 
     } else if (player.status == AVPlayerItemStatusUnknown) { 
      NSLog(@"AVPlayer Unknown"); 
     } 
    } 
} 

-(IBAction) BtnPlay:(id)sender { 
    [player play]; 
} 

-(IBAction) BtnPause:(id)sender { 
    [player pause]; 
} 

Отъезд Objective-C source code для рабочий пример этого. Надеюсь, это поможет!

-Update 12/7/2015 У меня теперь есть Swift пример исходного кода view here.

+0

NSString * path = [[NSBundle mainBundle] pathForResource: @ "MyAudio" ofType: @ "mp3"]; может у объяснить эту строку, пожалуйста .. откуда у вас загружается mp3 .. – ChenSmile

+0

@stitz у вас есть решение для того же самого для swift с AVPlayer? Я столкнулся с той же проблемой –

+1

@PenkeySuresh Я уверен: https://github.com/davestitz/iOS-AvPlayer-Swift-Demo – stitz

3

Да, это возможно скачать и сохранить .mp3 (или любой файл) в каталог NSDocument, а затем вы можете извлечь из него и воспроизвести с помощью AVAudioPlayer.

NSString *downloadURL=**your url to download .mp3 file** 

NSURL *url = [NSURLURLWithString:downloadURL]; 

NSURLConnectionalloc *downloadFileConnection = [[[NSURLConnectionalloc] initWithRequest:  [NSURLRequestrequestWithURL:url] delegate:self] autorelease];//initialize NSURLConnection 

NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 

NSString *fileDocPath = [NSStringstringWithFormat:@"%@/",docDir];//document directory path 

[fileDocPathretain]; 

NSFileManager *filemanager=[ NSFileManager defaultManager ]; 

NSError *error; 

if([filemanager fileExistsAtPath:fileDocPath]) 
{ 

//just check existence of files in document directory 
} 

NSURLConnection is used to download the content.NSURLConnection Delegate methods are used to support downloading. 

(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 

} 
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
NSFileManager *filemanager=[NSFileManagerdefaultManager]; 
if(![filemanager fileExistsAtPath:filePath]) 
{ 
[[NSFileManagerdefaultManager] createFileAtPath:fileDocPath contents:nil attributes:nil]; 

} 
NSFileHandle *handle = [NSFileHandlefileHandleForWritingAtPath:filePath]; 

[handle seekToEndOfFile]; 

[handle writeData:data]; 

[handle closeFile]; 
} 

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
UIAlertView *alertView=[[UIAlertViewalloc]initWithTitle:@”"message: 
[NSStringstringWithFormat:@"Connection failed!\n Error - %@ ", [error localizedDescription]] delegate:nilcancelButtonTitle:@”Ok”otherButtonTitles:nil]; 
    [alertView show]; 
    [alertView release]; 
    [downloadFileConnectioncancel];//cancel downloding 
    } 

Получить загруженное аудио и играть:

NSString *docDir1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 

    NSString *myfilepath = [docDir1 stringByAppendingPathComponent:YourAudioNameinNSDOCDir]; 

    NSLog(@”url:%@”,myfilepath); 

    NSURL *AudioURL = [[[NSURLalloc]initFileURLWithPath:myfilepath]autorelease]; 

Просто написать код для воспроизведения аудио с помощью AudioURL

Я хотел бы знать, если у вас какие-либо разъяснения по этому вопросу.

Спасибо

+0

Спасибо за образец кода.Мне нужно использовать AVPlayer вместо AVAudioPlayer для этого проекта. – stitz

+0

Будет ли он работать нормально, если я попытаюсь воспроизвести аудио с AVPlayer сразу после запуска запроса (или получения первого фрагмента)? Что произойдет, если моей скорости загрузки недостаточно для воспроизведения в реальном времени? –

+1

Привет @PavelAlexeev Я сейчас пытаюсь сделать очень похожее. Вы когда-нибудь получали что-то подобное? –

1

его очень трудно воспроизвести песню, используя AVPlayer, почему вы не используете MPMoviePlayerController игрока. У меня есть песня для воспроизведения из каталога документов. Я отправляю код PLS, ссылаясь на этот файл .its работает отлично .and также u прямо из url live.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *publicDocumentsDir = [paths objectAtIndex:0]; 
NSString *dataPath = [publicDocumentsDir stringByAppendingPathComponent:@"Ringtone"]; 
NSString *fullPath = [dataPath stringByAppendingPathComponent:[obj.DownloadArray objectAtIndex:obj.tagvalue]]; 
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO]; 


NSURL *url = [NSURL fileURLWithPath:fullPath]; 

videoPlayer =[[MPMoviePlayerController alloc] initWithContentURL: url]; 
[[videoPlayer view] setFrame: [self.view bounds]]; 
[vvideo addSubview: [videoPlayer view]]; 


videoPlayer.view.frame=CGRectMake(0, 0,260, 100); 
videoPlayer.view.backgroundColor=[UIColor clearColor]; 
videoPlayer.controlStyle = MPMovieControlStyleFullscreen; 
videoPlayer.shouldAutoplay = YES; 
[videoPlayer play]; 
videoPlayer.repeatMode=YES; 


NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 
[notificationCenter addObserver:self selector:@selector(moviePlayerEvent:) name:MPMoviePlayerLoadStateDidChangeNotification object:videoPlayer]; 


/* NSNotificationCenter *notificationCenter1 = [NSNotificationCenter defaultCenter]; 
[notificationCenter addObserver:self selector:@selector(moviePlayerEvent1:) name:MPMoviePlaybackStateStopped object:videoPlayer]; 
*/ 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(playbackStateChange:) 
              name:MPMoviePlayerLoadStateDidChangeNotification 
              object:videoPlayer]; 
} 

-(void)playbackStateChange:(NSNotification*)notification{ 

if([[UIApplication sharedApplication]respondsToSelector:@selector(setStatusBarHidden: withAnimation:)]) 
    { 
     [[UIApplication sharedApplication] setStatusBarHidden:NO 
              withAnimation:UIStatusBarAnimationNone]; 
    } 
    else 
    { 

     [[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO]; 
    } 
} 

-(void)moviePlayerEvent:(NSNotification*)aNotification{ 


    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO]; 


} 

    -(void)moviePlayerEvent1:(NSNotification*)aNotification{ 

[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO]; 

} 
+0

Класс MPMoviePlayerController устарел в iOS 9. https://developer.apple.com/reference/mediaplayer/mpmovieplayercontroller – RenniePet

9

Я получил AVPlayer работать с локальной URL, предваряя file:// в местный URL

NSURL * localURL = [NSURL URLWithString:[@"file://" stringByAppendingString:YOUR_LOCAL_URL]]; 
AVPlayer * player = [[AVPlayer alloc] initWithURL:localURL]; 
+0

Это исправило мою проблему. Обязательно проверьте, добавляет ли файл «файл: //» в начало вашего пути исправление проблемы. – Jonathan

+0

Вместо NSURL * localURL = [NSURL URLWithString: [@ "file: //" stringByAppendingString: YOUR_LOCAL_URL]]; вы можете написать NSURL * localURL = [NSURL fileURLWithString: YOUR_LOCAL_URL]; – MARTIN

2

Попробуйте

NSString*thePath=[[NSBundle mainBundle] pathForResource:@"yourVideo" ofType:@"MOV"]; 
NSURL*theurl=[NSURL fileURLWithPath:thePath]; 
Смежные вопросы