iOS:降低包含iPod音乐的MPMediaItem的比特率 [英] iOS: lowering bitrate of MPMediaItem containing an iPod music

查看:85
本文介绍了iOS:降低包含iPod音乐的MPMediaItem的比特率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个向视频添加主题音乐的应用程序.

I'm making an app which add a theme music to an video.

一些用户抱怨说,如果他们的音乐采用苹果无损格式,则视频将太大.

Some user complains that if their music is in apple lossless format, the video will be too large.

我发现这是因为我使用的AVMutableComposition只是将原始音乐格式放入了我生成的视频中.

I found that is because the AVMutableComposition I use just put the original music format in to the video I generated.

那么有什么办法可以降低MPMediaItem中音乐的比特率,或更改其编码格式?

So is there any way I can lower the bitrate of the music in MPMediaItem, or change the format it is encoded?

这是我用来向视频添加音乐的代码的代码段.

This is a code snippet of the code I use to add music to video.

AVMutableComposition* mixComposition = [AVMutableComposition composition];

AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                                    preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                                    ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                                     atTime:kCMTimeZero error:nil];

AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                               preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                               ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                                atTime:kCMTimeZero error:nil];

AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                      presetName:AVAssetExportPresetPassthrough];

NSURL    *exportUrl = [NSURL fileURLWithPath:_videoOutputPath];

if ([[NSFileManager defaultManager] fileExistsAtPath:_videoOutputPath]){
    [[NSFileManager defaultManager] removeItemAtPath:_videoOutputPath error:nil];
}

_assetExport.outputFileType = @"com.apple.quicktime-movie";

_assetExport.outputURL = exportUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;

[_assetExport exportAsynchronouslyWithCompletionHandler:^(void ) {}

推荐答案

我终于明白了,这是我使用的代码:

I finally got it, this is the code I use:

static NSString * const kWriterInputIsReadyForMoreData = @"readyForMoreMediaData";

#import <AVFoundation/AVFoundation.h>
@implementation AudioUtil
{
    AVAssetReader *_assetReader;
    AVAssetWriter *_assetWriter;
    AVAssetWriterInput *_assetWriterInput;
    AVAssetReaderTrackOutput *_readerOutput;
    void (^_callback)(BOOL);
    CMSampleBufferRef _sampleBufferToAppend;
}

-(void)downSamplingAudioWithSourceURL:(NSURL *)sourceURL destinationURL:(NSURL *)destURL timeRange:(CMTimeRange)timeRange  callBack:(void (^)(BOOL))callback
{
    NSError *error = nil;
    _callback = callback;

    [[NSFileManager defaultManager] removeItemAtURL:destURL error:nil];

//initialize reader
AVURLAsset *inputAsset = [AVURLAsset assetWithURL:sourceURL];
_assetReader = [[AVAssetReader alloc] initWithAsset:inputAsset error:&error];
_assetReader.timeRange = timeRange;
AVAssetTrack* track = [[inputAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

NSMutableDictionary* audioReadSettings = [NSMutableDictionary dictionary];
audioReadSettings[AVFormatIDKey] = @(kAudioFormatLinearPCM);
audioReadSettings[AVNumberOfChannelsKey] = @([QLVideoFormatProvider audioChannelCount]);

_readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:audioReadSettings];
NSAssert([_assetReader canAddOutput:_readerOutput], @"reader can't add output");
[_assetReader addOutput:_readerOutput];

//initialize writer
_assetWriter = [[AVAssetWriter alloc] initWithURL:destURL fileType:[QLVideoFormatProvider audioFileType] error:nil];

NSMutableDictionary *audioOutputSettings = [NSMutableDictionary dictionary];
audioOutputSettings[AVFormatIDKey] = [QLVideoFormatProvider audioFormatKeyForEncoder];
audioOutputSettings[AVNumberOfChannelsKey] = @([QLVideoFormatProvider audioChannelCount]);
audioOutputSettings[AVSampleRateKey] = @([QLVideoFormatProvider audioSampleRate]);
audioOutputSettings[AVEncoderBitRateKey] = @([QLVideoFormatProvider audioBitrate]);

_assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings];
[_assetWriter addInput:_assetWriterInput];

//start
[_assetWriter startWriting];
[_assetWriter startSessionAtSourceTime:kCMTimeZero];
BOOL canStartReading = [_assetReader startReading];
NSLog(@"can start reading %d",canStartReading);
if (!canStartReading) {
    callback(NO);
    return;
}

[_assetWriterInput addObserver:self forKeyPath:kWriterInputIsReadyForMoreData options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:NULL];
_sampleBufferToAppend = [_readerOutput copyNextSampleBuffer];

    [self appendBufferToAppend];
}

-(void)appendBufferToAppend
{
    if ([_assetWriterInput isReadyForMoreMediaData]) {
        if (_sampleBufferToAppend) {
            [_assetWriterInput appendSampleBuffer:_sampleBufferToAppend];
            CFRelease(_sampleBufferToAppend);
        }
        _sampleBufferToAppend = [_readerOutput copyNextSampleBuffer];
        if (_sampleBufferToAppend) {
            [self appendBufferToAppend];
        }
        else {
            [_assetWriter finishWritingWithCompletionHandler:^(){
                if (_callback) {
                    _callback(_assetWriter.status == AVAssetWriterStatusCompleted);
                };
            }];
        }
    }
    else {

    }
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:kWriterInputIsReadyForMoreData]) {
        if ([change[NSKeyValueChangeNewKey] boolValue] == YES) {
            [self appendBufferToAppend];
        }
    }
}

这篇关于iOS:降低包含iPod音乐的MPMediaItem的比特率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆