【问题标题】:Getting NSData out of music file in iPhone从 iPhone 中的音乐文件中获取 NSData
【发布时间】:2012-10-30 07:57:03
【问题描述】:

我已从我的 iPhone 设备中检索到所有音乐和视频。我现在被困在将它们保存到我的应用程序中,我无法从文件中获取原始数据。任何人都可以帮我找到解决方案。这是我用来获取音乐文件的代码。

MPMediaQuery *deviceiPod = [[MPMediaQuery alloc] init];
NSArray *itemsFromGenericQuery = [deviceiPod items];
for (MPMediaItem *media in itemsFromGenericQuery){
 //i get the media item here.
}

如何将其转换为 NSData ?? 这是我试图获取数据的原因

audioURL = [media valueForProperty:MPMediaItemPropertyAssetURL];//here i get the asset url
NSData *soundData = [NSData dataWithContentsOfURL:audioURL];

使用它对我来说毫无用处。我力图从LocalAssestURL 获取数据。对此的任何解决方案。提前致谢

【问题讨论】:

    标签: iphone nsdata assets mpmediaitem


    【解决方案1】:

    这不是一项简单的任务——Apple 的 SDK 通常无法为简单任务提供简单的 API。这是我在其中一项调整中使用的代码,以便从资产中获取原始 PCM 数据。您需要将 AVFoundation 和 CoreMedia 框架添加到您的项目中才能使其正常工作:

    #import <AVFoundation/AVFoundation.h>
    #import <CoreMedia/CoreMedia.h>
    
    MPMediaItem *item = // obtain the media item
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    // Get raw PCM data from the track
    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    NSMutableData *data = [[NSMutableData alloc] init];
    
    const uint32_t sampleRate = 16000; // 16k sample/sec
    const uint16_t bitDepth = 16; // 16 bit/sample/channel
    const uint16_t channels = 2; // 2 channel/sample (stereo)
    
    NSDictionary *opts = [NSDictionary dictionary];
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:assetURL options:opts];
    AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:NULL];
    NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:
        [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
        [NSNumber numberWithFloat:(float)sampleRate], AVSampleRateKey,
        [NSNumber numberWithInt:bitDepth], AVLinearPCMBitDepthKey,
        [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
        [NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
        [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey, nil];
    
    AVAssetReaderTrackOutput *output = [[AVAssetReaderTrackOutput alloc] initWithTrack:[[asset tracks] objectAtIndex:0] outputSettings:settings];
    [asset release];
    [reader addOutput:output];
    [reader startReading];
    
    // read the samples from the asset and append them subsequently
    while ([reader status] != AVAssetReaderStatusCompleted) {
        CMSampleBufferRef buffer = [output copyNextSampleBuffer];
        if (buffer == NULL) continue;
    
        CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(buffer);
        size_t size = CMBlockBufferGetDataLength(blockBuffer);
        uint8_t *outBytes = malloc(size);
        CMBlockBufferCopyDataBytes(blockBuffer, 0, size, outBytes);
        CMSampleBufferInvalidate(buffer);
        CFRelease(buffer);
        [data appendBytes:outBytes length:size];
        free(outBytes);
    }
    
    [output release];
    [reader release];
    [pool release];
    

    这里data 将包含曲目的原始PCM数据;您可以使用某种编码来压缩它,例如我使用 FLAC 编解码器库。

    请参阅original source code here

    【讨论】:

    • 这段代码在 iphone 4 上需要超过 2 秒的单个音频文件。有什么方法可以让这个文件读取得更快吗?
    • 您好,对于压缩,我使用了 zlib,但它几乎没有减少文件大小。我在这里使用了代码-stackoverflow.com/questions/8425012/…
    • 你知道为什么吗?
    • 我检查了它,对于 mp3 来说效果很好。但是,来自 iTunes 的文件返回空的 NSData。当我使用 AVAssetExportSession 时,我可以在我的存储中获取文件。但我想把它作为 NSData 和 MP3 文件一样。你知道原因或解决方案吗?
    • 我使用了这个代码,它返回了 15 MB 的数据,而我选择了一个 5MB 的 Mp3。你能帮我把Mp3转换成实际重量吗..谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    相关资源
    最近更新 更多