ScaleTimeRange не влияет на тип аудио AVMutableCompositionTrack

Я работаю над простым приложением для редактирования видео. Я хочу добавить замедленное движение к моему приложению. Я замечаю, что в классе AVMutableCompositionTrack существует метод scaleTimeRange, поэтому я использую его для достижения своей цели. Я обнаружил, что scaleTimeRange очень хорошо работает на видеодорожке, но не оказывает никакого влияния на звуковую дорожку. Это означает, что звуковая дорожка по-прежнему воспроизводится с начальной скоростью.

Следуйте моему коду:

    CMTime insertionPoint = kCMTimeZero;

    double wholeDuration = CMTimeGetSeconds([asset duration]);
    double doubleDuration = CMTimeGetSeconds([asset duration])*2.0;
    CMTime trimmedDuration = CMTimeMakeWithSeconds(wholeDuration, 600.0);

    // Create a new composition
    self.mutableComposition = [AVMutableComposition composition];

    // Insert video and audio tracks from AVAsset
    if(assetVideoTrack != nil) {
        AVMutableCompositionTrack *compositionVideoTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
        [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, trimmedDuration) ofTrack:assetVideoTrack atTime:insertionPoint error:&error];

        [compositionVideoTrack scaleTimeRange:CMTimeRangeMake(kCMTimeZero, trimmedDuration) toDuration:CMTimeMakeWithSeconds(doubleDuration, 600.0)];
    }
    if(assetAudioTrack != nil) {
        AVMutableCompositionTrack *compositionAudioTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
        [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, trimmedDuration) ofTrack:assetAudioTrack atTime:insertionPoint error:&error];

        [compositionAudioTrack scaleTimeRange:CMTimeRangeMake(kCMTimeZero, trimmedDuration) toDuration:CMTimeMakeWithSeconds(doubleDuration, 600.0)];
    }

Может кто-нибудь дать мне несколько советов о проблеме? Спасибо!

Ответ 1

ScaleTimeRange не работает для звука из-за ошибки в apple api (ID ошибки: 14616144). Тем не менее, время масштабирования аудио может быть выполнено с использованием повторной выборки. Если аудио сэмплировано на частоте 48 кГц, повторите выбор до 96 кГц и воспроизведите аудио с частотой 48 кГц, это займет в два раза больше времени для воспроизведения. Как правило:

scaledSampleRate = (orignalSampleRate / playRate);
playRate = (originalSampleRate / scaledSampleRate);

Шаг будет опущен, если это нежелательно. Решение может быть сторонним api. Если вы можете извлечь аудио на отдельный плеер, я думаю, вы можете использовать AVAudioPlayer, где вы можете установить скорость воспроизведения:

player = [[AVAudioPlayer alloc] initWithContentsOfURL:
                  [NSURL fileURLWithPath:path] error:&err];
        player.volume = 0.4f;
        player.enableRate=YES;
        [player prepareToPlay];
        [player setNumberOfLoops:0];
        player.rate=2.0f;
        [player play];

Ответ 2

Чтобы играть медленным mo со звуком, просто установите соответствующий алгоритм audioTimePitchAlgorithm для AVPlayerItem

playerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmVarispeed;