3

AVAudioPlayerいくつかのmp3ファイルを再生したい。それらのいくつかを再生しますが、再生できないファイルが1つあります。

ファイルを再生するには、デバイスからアプリケーションフォルダーにダウンロードし、次のように初期化します。

[[AVAudioPlayer alloc] initWithContentsOfURL:soundPath error:nil];

ファイルを再生する方法は?なぜ再生されないのですか?

ファイルへのリンク:abc.mp3

編集:

(これがエラーを示すコードです。コード内にREADMEがあります。デバイスで試してください。)

***.pch

#import <Availability.h>

#ifndef __IPHONE_4_0
#warning "This project uses features only available in iOS SDK 4.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import <SystemConfiguration/SystemConfiguration.h>
    #import <MobileCoreServices/MobileCoreServices.h>
    #import <AVFoundation/AVFoundation.h>
    #import <AudioToolbox/AudioToolbox.h>
#endif



ViewController.h

#import <UIKit/UIKit.h>
#import "AFNetworking.h"

@interface SCRViewController : UIViewController <AVAudioPlayerDelegate>
{
    UIButton *button;
    __block UIProgressView *view;
    NSOperationQueue *queue;
    __block BOOL isFile;
    UIButton *play;
    NSString *path;
    AVAudioPlayer *_player;
}

@end


ViewController.m

#import "ViewController.h"

@implementation SCRViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setBackgroundColor:[UIColor yellowColor]];
    [button setFrame:CGRectMake(50, 50, 220, 50)];
    [button addTarget:self action:@selector(download) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"Download" forState:UIControlStateNormal];
    [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
    [self.view addSubview:button];

    play = [UIButton buttonWithType:UIButtonTypeCustom];
    [play setBackgroundColor:[UIColor yellowColor]];
    [play setFrame:CGRectMake(50, 150, 220, 50)];
    [play addTarget:self action:@selector(play) forControlEvents:UIControlEventTouchUpInside];
    [play setTitle:@"Play" forState:UIControlStateNormal];
    [play setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [play setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
    [self.view addSubview:play];

    self->view = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
    self->view.frame = CGRectMake(10, 120, 300, 20);
    [self->view setProgress:0];
    [self.view addSubview:self->view];

    queue = [[NSOperationQueue alloc] init];

    isFile = NO;
}

- (void) download
{
    [button setBackgroundColor:[UIColor brownColor]];
    [button setTitleColor:[UIColor whiteColor] forState:UIControlStateDisabled];
    [button setEnabled:NO];

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://iwheelbuy.com/abc.mp3"]];

    //-------------------------------------------------------
    //-------------------------------------------------------
    // READ ME
    //-------------------------------------------------------
    //-------------------------------------------------------
    // Test in on device
    // I have uploaded another song for you. You can change link to http://iwheelbuy.com/def.mp3 and check the result
    // def.mp3 works fine on the device
    //-------------------------------------------------------
    //-------------------------------------------------------

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    path = [path stringByAppendingPathComponent:@"song"];

    if ( [[NSFileManager defaultManager] fileExistsAtPath:path])
        [[NSFileManager defaultManager] removeItemAtPath:path error:nil];

    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
     {
         isFile = YES;
     } failure:^(AFHTTPRequestOperation *operation, NSError *error)
     {
         //
     }];
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
     {
         CGFloat done = (CGFloat)((int)totalBytesRead);
         CGFloat expected = (CGFloat)((int)totalBytesExpectedToRead);
         CGFloat progress = done / expected;
         self->view.progress = progress;
     }];
    [queue addOperation:operation];
}

- (void) play
{
    if (isFile)
    {
        NSError *error = nil;
        NSURL *url = [NSURL fileURLWithPath:path];
        _player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
        if(error || !_player)
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:[error description] delegate:nil cancelButtonTitle:@"Try def.mp3" otherButtonTitles:nil];
            [alert show];
        }
        else
        {
            [_player play]; // plays fine
            [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
            [[AVAudioSession sharedInstance] setActive: YES error: nil];
        }
    }
    else
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"Download the file plz" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alert show];
    }
}

@end
4

2 に答える 2

7

非ARC

それ自体は保持されないため、再生中に保持する必要があります。割り当てが解除されると、すぐに再生が停止します。

アーク

AVAudioPlayerクラスでインスタンスを保持する必要があります。そして、再生が停止したら放します。例えば、

#import <AVFoundation/AVFoundation.h>

@interface TAViewController () <AVAudioPlayerDelegate> {
    AVAudioPlayer *_somePlayer;   // strong reference
}
@end

@implementation TAViewController

- (IBAction)playAudio:(id)sender
{
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"kogmawjoke" withExtension:@"mp3"];
    _somePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
    _somePlayer.delegate = self;
    [_somePlayer play];
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    if (player == _somePlayer) {
        _somePlayer = nil;
    }
}

@end
于 2012-10-04T13:13:00.900 に答える
1
http://bugreport.apple.com

エンジニアリングは、次の情報に基づいて、この問題が意図したとおりに動作することを確認しました。

添付のサンプルアプリで再現できますが、これはAudioFileから予想される動作です。

問題はAVAudioPlayer、ファイル拡張子のないURLで初期化されており、対応するファイルに有効なタグがないことですID3。ファイル拡張子または有効なデータがないと、正しいファイル形式を判別できないため、そのようなファイルを開くことができません。予想される動作です。

添付のサンプルコード:

path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

path = [path stringByAppendingPathComponent:@"song"];

->パスは次のようになります。

/ var / mobile / Applications / 2FFD0147-E56B-47D4-B143-A9F19BE92818 / Documents / song

->注:最後にファイル拡張子はありません。

有効なタグサイズ(0x927)を持つdef.mp3とは異なり、abc.mp3には無効ID3なタグサイズ(0x2EE)があります。したがって、これらが拡張子なしで「…./song」として指定されている場合、AudioFileはデータを調べて、def.mp3の有効な同期ワードを検出しますが、abc.mp3の有効な同期ワードは検出しません。

ただし、に置き換えるstringByAppendingPathComponent:@"song"stringByAppendingPathComponent:@"song.mp3"abc.mp3は成功し、他のmp3ファイル全般に役立つ可能性があります。

この問題は解決されたと見なします。この問題に関して質問や懸念がある場合は、レポートを直接更新してください(http://bugreport.apple.com)。

この問題をお知らせいただきありがとうございます。

于 2012-11-17T01:41:11.983 に答える