AVAssetReader Ищу - PullRequest
       1

AVAssetReader Ищу

4 голосов
/ 21 мая 2011

Мне нужно поискать аудиофайл и вытащить куски. Я пытаюсь использовать AVAssetReader. Ошибка, которую я вижу, заключается в том, что если я читаю аудио в течение определенного периода времени из разных смещений, среднее значение (порция), которое я получаю, отличается.

Например, если я читаю звук от 0,1 с до 0,5 с, я получаю разные куски, которые я получаю, отличаются, если я читаю от 0,2 до 0,5 с

Ниже приведен пример кода, который демонстрирует это

#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>

+ (void) test
{
    NSURL* path = [[NSBundle mainBundle] URLForResource:@"music" withExtension:@"mp3"];

    [self test:path sample:1 showChunks:5];
    [self test:path sample:2 showChunks:4];
    [self test:path sample:3 showChunks:3];
}

+(void) test:(NSURL*) url sample:(NSInteger) sample showChunks:(NSInteger) chunkCount
{
#define CHUNK 800
#define SAMPLE_RATE 8000
    AVURLAsset* asset = [AVURLAsset URLAssetWithURL:url options:nil];
    NSError *assetError = nil;
    AVAssetReader* assetReader = [AVAssetReader assetReaderWithAsset:asset error:&assetError];

    CMTime startTime = CMTimeMake(sample*CHUNK, SAMPLE_RATE);
    CMTimeShow(startTime);

    CMTimeRange timeRange = CMTimeRangeMake(startTime, kCMTimePositiveInfinity);
    assetReader.timeRange = timeRange;

    NSDictionary* dict = nil;
    dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:SAMPLE_RATE], AVSampleRateKey, [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey, nil];


    AVAssetReaderAudioMixOutput* assetReaderOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:asset.tracks audioSettings: dict];
    if (! [assetReader canAddOutput: assetReaderOutput]) {
        NSLog (@"error: Cannot add output reader");
        assetReader = nil;
        return;
    }

    [assetReader addOutput: assetReaderOutput];

    [assetReader startReading];

    CMSampleBufferRef nextBuffer;

    if (!(nextBuffer = [assetReaderOutput copyNextSampleBuffer]))
    {
        return;
    }
    CMSampleBufferGetTotalSampleSize (nextBuffer);
    // Extract bytes from buffer
    CMBlockBufferRef dataBuffer = CMSampleBufferGetDataBuffer(nextBuffer);

    NSInteger len = CMBlockBufferGetDataLength(dataBuffer);
    if (len < chunkCount*CHUNK)
    {
        printf("CHUNK is to big");
        return;
    }
    UInt8* buf = malloc(len);
    CMBlockBufferCopyDataBytes(dataBuffer, 0, len, buf);

    for (int ii = 0; ii < chunkCount*CHUNK; ii+=CHUNK)
    {
        CGFloat av = 0;
        for (int jj = 0; jj < CHUNK; jj++)
        {
            av += (CGFloat) buf[jj+ii];
        }
        printf("Time: %f av: %f\n", (CGFloat)(ii+CHUNK*sample)/(CGFloat)SAMPLE_RATE,  av/(CGFloat)CHUNK);
    }
    printf("\n");

    free(buf);


}

Это вывод

{800/8000 = 0.100}
Time: 0.100000 av: 149.013748
Time: 0.200000 av: 100.323753
Time: 0.300000 av: 146.991257
Time: 0.400000 av: 106.763748
Time: 0.500000 av: 145.020004

{1600/8000 = 0.200}
Time: 0.200000 av: 145.011246
Time: 0.300000 av: 110.718750
Time: 0.400000 av: 154.543747
Time: 0.500000 av: 112.025002

{2400/8000 = 0.300}
Time: 0.300000 av: 149.278748
Time: 0.400000 av: 104.477501
Time: 0.500000 av: 158.162506

Помогите пожалуйста

Ответы [ 2 ]

6 голосов
/ 16 июля 2011

Мне кажется, что ваша проблема заключается в предположении, что следующий код точно ищет startTime:

CMTimeRange timeRange = CMTimeRangeMake(startTime, kCMTimePositiveInfinity);
assetReader.timeRange = timeRange;

Вы можете проверить это с помощью вызова

CMSampleBufferGetOutputPresentationTimeStamp (nextBuffer);

Отсюда вы сможете увидеть точное время (в секундах) запуска буфера.

0 голосов
/ 08 ноября 2012

По моему опыту, поиск с

assetReader.timeRange = CMTimeRangeMake(CMTimeMake(sample, sample_rate), kCMTimePositiveInfinity)

работает отлично.С поиском нет проблем с точностью.

Вы можете столкнуться с проблемой появления: на самом деле AVAssetReader кажется исчезающим в первых 1024 выборках (возможно, немного больше).Я исправил это, прочитав 1024 семпла до позиции, которую я действительно хочу прочитать, а затем пропустил эти 1024 семпла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...