上传声音文件到服务器

Posted

技术标签:

【中文标题】上传声音文件到服务器【英文标题】:Uploading Sound file to server 【发布时间】:2013-08-04 00:59:40 【问题描述】:

我正在尝试将已经采用 m4a 格式的录制声音文件上传到 Web 服务器。

这里有一些代码需要更正:

- (void)viewDidLoad

    [super viewDidLoad];

    // Disable Stop/Play button when application launches
    [stopButton setEnabled:NO];
    [playButton setEnabled:NO];

    // Set the audio file
    pathComponents = [NSArray arrayWithObjects:
                               [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
                               @"MyAudioMemo.m4a",
                               nil];
    outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];

    // Setup audio session
    AVAudiosession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

    // Define the recorder setting
    NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

    [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
    [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

    // Initiate and prepare the recorder
    recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:nil];
    recorder.delegate = self;
    recorder.meteringEnabled = YES;
    [recorder prepareToRecord];


- (IBAction)recordPauseTapped:(id)sender 
    // Stop the audio player before recording
    if (player.playing) 
        [player stop];
    

    if (!recorder.recording) 
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setActive:YES error:nil];

        // Start recording
        [recorder record];
        [recordPauseButton setTitle:@"Pause" forState:UIControlStateNormal];

     else 

        // Pause recording
        [recorder pause];
        [recordPauseButton setTitle:@"Record" forState:UIControlStateNormal];
    

    [stopButton setEnabled:YES];
    [playButton setEnabled:NO];


- (IBAction)playTapped:(id)sender 
    if (!recorder.recording)
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
        [player setDelegate:self];
        [player play];
    


-(IBAction)uploadSound 

    NSURL *theURL = [NSURL URLWithString:outputFileURL];
    NSData *theData = [NSData dataWithContentsOfURL:[NSURL URLWithString:theURL]];

    NSString *urlString = @"http://drewgarcia23.3owl.com/upload.php";

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];

    NSString *boundary = [NSString stringWithString:@"---------------------------14737809831466499882746641449"];
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request addValue:contentType forHTTPHeaderField:@"Content-Type"];

    NSMutableData *body = [NSMutableData data];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"userfile\"; filename=\".mov\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:theData]];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:body];

    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

    NSLog(@"%@", returnString);

一切正常,除了上传到服务器。我收到此错误:

* 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[NSURL 长度]:无法识别的选择器已发送到实例 0x7a9a590”

IBActionuploadSound中的这段代码有关:

NSURL *theURL = [NSURL URLWithString:outputFileURL];
NSData *theData = [NSData dataWithContentsOfURL:[NSURL URLWithString:theURL]];

有什么想法吗?

【问题讨论】:

顺便说一句,我不建议在主队列上执行同步网络请求。 (在处理网络请求时,您的应用程序可能会变得无响应,如果处理时间过长,在极端情况下,看门狗进程甚至可能会杀死您的应用程序。)我建议采用某种形式的异步网络上传过程(例如sendAsynchronousRequest) . 【参考方案1】:

一个问题是您正在调用URLWithString,将NSURL 传递给它,但它期待NSString

例如,考虑以下行:

NSURL *theURL = [NSURL URLWithString:outputFileURL];
NSData *theData = [NSData dataWithContentsOfURL:[NSURL URLWithString:theURL]];

这里有两个问题。首先,在第一行中,outputFileURL 已经是NSURL,因此在创建theURL 对象时调用URLWithString 是没有意义的。 outputFileURL 已经是 NSURL,因此无需转换。其次,您在第二行中有另一个多余的URLWithString 调用,您将在其中使用theURL,这已经是NSURL(或者如果第一行成功,将会是)。

您不需要这两个URLWithString 调用中的任何一个。应该很简单:

NSData *theData = [NSData dataWithContentsOfURL:outputFileURL];

只有在尝试将NSString 转换为NSURL 时,才应调用URLWithString。但如果你已经有一个 NSURL 对象,你永远不会调用它。

【讨论】:

以上是关于上传声音文件到服务器的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ASP.NET 和 C# 将录音上传到 Sound Cloud?

asp.net 从 mp3 创建波形图像

媒体录音机声音质量差

从自己的声音文件语音到文本

在网页上录制、保存和播放保存的声音文件

iOS开发中上传Word文件之上传Word文件到服务器