AVPlayer и локальные файлы
Я создаю MP3-плеер для iOS, который воспроизводит аудиофайлы, размещенные в Интернете. Я хочу предложить возможность играть в файлы в автономном режиме, поэтому я загружаю файлы с помощью ASIHTTP, но я не могу найти информацию об инициализации AVPlayer с помощью mp3 в каталоге документов приложения. Кто-нибудь делал это раньше? Возможно ли это?
* Я разместил ответ ниже, который показывает, как использовать IOS AvPlayer для локальных и http файлов. Надеюсь, это поможет!
Ответы
Ответ 1
Я решил ответить на свой вопрос, потому что мне показалось, что очень мало документации о том, как использовать предоставленный Apple AVPlayer для локальных и потоковых (поверх http) файлов. Чтобы помочь понять решение, я собрал образец проекта GitHub в 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 исходным кодом для рабочего примера этого.
Надеюсь, это поможет!
-Update 12/7/2015 Теперь у меня есть Swift пример исходного кода, который вы можете посмотреть здесь.
Ответ 2
Я получил AVPlayer
для работы с локальным URL, добавив file://
к моему локальному URL
NSURL * localURL = [NSURL URLWithString:[@"file://" stringByAppendingString:YOUR_LOCAL_URL]];
AVPlayer * player = [[AVPlayer alloc] initWithURL:localURL];
Ответ 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
Мне нравится знать, есть ли у вас какие-либо разъяснения в этом отношении.
Спасибо
Ответ 4
Попробуйте это
NSString*thePath=[[NSBundle mainBundle] pathForResource:@"yourVideo" ofType:@"MOV"];
NSURL*theurl=[NSURL fileURLWithPath:thePath];
Ответ 5
очень сложно воспроизвести песню, используя Avplayer, почему вы не используете плеер MPMoviePlayerController. У меня есть песня для воспроизведения из каталога документов. Я отправляю код PLS, ссылаясь на это. Работает отлично .and также u непосредственно из URL-адреса вживую.
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];
}
Ответ 6
Быстрая версия для локального воспроизведения, если у меня в комплекте есть файл "shelter.mp3":
@IBAction func button(_ sender: Any?) {
guard let url = Bundle.main.url(forResource: "shelter", withExtension: "mp3") else {
return
}
let player = AVPlayer(url: url)
player.play()
playerView?.player = player;
}
Смотрите здесь для получения подробной информации о playerView или воспроизведении удаленного URL.