如何修剪音乐库文件并将其保存为文档目录

时间:2015-05-19 09:32:33

标签: objective-c cocoa-touch avfoundation core-audio

-(BOOL)trimAudioFileAtPath:(NSString *)inputFilename
                 start:(float)start
                   end:(float) stop{

           NSString *outputFilename = @"File Path";
           NSError *error = nil; NSFileManager *fileManager = [NSFileManager    defaultManager]; if ([fileManager fileExistsAtPath:outputFilename]) {

           if (![fileManager removeItemAtPath:outputFilename error:&error]) {

           DebugLog(@"error file remove:%@",error);    } else {
           DebugLog(@"sucess remove file");    
} }

       NSURL *audioFileInput = [NSURL fileURLWithPath:inputFilename]; 
       NSURL    *audioFileOutput = [NSURL fileURLWithPath:outputFilename];
       if (!audioFileInput || !audioFileOutput){    return NO; }
      [[NSFileManager defaultManager] removeItemAtURL:audioFileOutput    error:NULL];

           AVMutableComposition *mutableComposition = [AVMutableComposition    composition]; // Create the video composition track.
           AVMutableCompositionTrack *mutableCompositionAudioTrack =    [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio    preferredTrackID:kCMPersistentTrackID_Invalid];
           NSLog(@"audioFileInput  %@",audioFileInput); AVURLAsset *assetUrl =    [AVURLAsset assetWithURL:audioFileInput];
           if ([[assetUrl tracksWithMediaType:AVMediaTypeAudio] count]==0) {    return NO;  }

    // Get the first music track from each asset. AVAssetTrack *audioAssetTrack = [[assetUrl tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; [mutableCompositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,audioAssetTrack.timeRange.duration) ofTrack:audioAssetTrack atTime:kCMTimeZero error:nil];

    // we need the audio asset to be at least 50 seconds long for this snippet

    CMTime startTime = CMTimeMake(start, 1); 
    CMTime stopTime = CMTimeMake(stop, 1);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime,stopTime); 
Float64 duration = CMTimeGetSeconds(exportTimeRange.duration);

// Create the export session with the composition and set the preset to the highest quality. 
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetAppleM4A];

if (duration > 6.0){

    AVMutableAudioMix *mutableAudioMix = [AVMutableAudioMix audioMix];
    // Create the audio mix input parameters object.
    AVMutableAudioMixInputParameters *mixParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:mutableCompositionAudioTrack];

    // float totalDutaion=mutableComposition.duration.value;
    float totalDutaion=duration;
    float lenth=totalDutaion/3;
    CMTime startCM = CMTimeMake(totalDutaion-lenth-1,mutableComposition.duration.timescale);
    CMTime endCM = CMTimeMake(lenth, mutableComposition.duration.timescale);

    // Set the volume ramp to slowly fade the audio out over the duration of the composition.
    [mixParameters setVolumeRampFromStartVolume:0.f toEndVolume:1.f timeRange:CMTimeRangeMake(startTime, endCM)];
    [mixParameters setVolumeRampFromStartVolume:1.f toEndVolume:0.f timeRange:CMTimeRangeMake(startCM,endCM)];

    // Attach the input parameters to the audio mix.
    mutableAudioMix.inputParameters = @[mixParameters];
    exportSession.audioMix=mutableAudioMix; }

if (exportSession == nil){

    return NO; }


exportSession.outputURL = audioFileOutput; exportSession.outputFileType = AVFileTypeAppleM4A; exportSession.timeRange = exportTimeRange;

[exportSession exportAsynchronouslyWithCompletionHandler:^  {
     if (AVAssetExportSessionStatusCompleted == exportSession.status)
     {
         // It worked!
     }
     else if (AVAssetExportSessionStatusFailed == exportSession.status)
     {
         // It failed...
     }  }]; return YES; }

我正在使用此功能修剪音乐文件中的音乐文件。当我尝试修剪位于bundle中的文件时,Above代码是工作文件。但是当我尝试使用与iTune音乐库中的输入文件相同的功能时,它不给轨道,即if([[assetUrl tracksWithMediaType:AVMediaTypeAudio] count] == 0){         返回NO;     }否。任何人都可以帮助修剪iTunes Libaray中的音乐

3 个答案:

答案 0 :(得分:0)

- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection
{
    if (mediaItemCollection) {
        NSLog(@"%@",[mediaItemCollection items]);
       // [musicPlayer setQueueWithItemCollection: mediaItemCollection];
       // [musicPlayer play];
    }

    [KVNProgress showWithStatus:@"Processing"];

    MPMediaItem *item =mediaItemCollection.representativeItem;
    NSURL* assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];


    // set up an AVAssetReader to read from the iPod Library
    AVURLAsset *songAsset =
    [AVURLAsset URLAssetWithURL:assetURL options:nil];

    NSError *assetError = nil;
    AVAssetReader *assetReader =[AVAssetReader assetReaderWithAsset:songAsset error:&assetError];
    if (assetError) {
        NSLog (@"error: %@", assetError);
        return;
    }


    AVAssetReaderOutput *assetReaderOutput =[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
      audioSettings: nil];

    if (! [assetReader canAddOutput: assetReaderOutput]) {
        NSLog (@"can't add reader output... die!");
        return;
    }
    [assetReader addOutput: assetReaderOutput];


//    NSArray *dirs = NSSearchPathForDirectoriesInDomains
//              (NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *documentsDirectoryPath = [dirs objectAtIndex:0];
//    NSString *exportPath = [documentsDirectoryPath stringByAppendingPathComponent:@"out.m4a"];
    NSString * exportPath =[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), @"out.m4a"];


    if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {

        [[NSFileManager defaultManager] removeItemAtPath:exportPath
                                                   error:nil];
    }
    NSURL *exportURL = [NSURL fileURLWithPath:exportPath];

    AVAssetWriter *assetWriter =[AVAssetWriter assetWriterWithURL:exportURL
                              fileType:AVFileTypeCoreAudioFormat
                                 error:&assetError];
    if (assetError) {
        NSLog (@"error: %@", assetError);
        return;
    }


    AudioChannelLayout channelLayout;
    memset(&channelLayout, 0, sizeof(AudioChannelLayout));
    channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
    NSDictionary *outputSettings =[NSDictionary dictionaryWithObjectsAndKeys:
                                   @(kAudioFormatLinearPCM), AVFormatIDKey,
                                   @44100.0, AVSampleRateKey,
                                   @2, AVNumberOfChannelsKey,
                                   [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)],AVChannelLayoutKey,
                                   @16, AVLinearPCMBitDepthKey,
                                   @NO, AVLinearPCMIsNonInterleaved,
                                   @NO,AVLinearPCMIsFloatKey,
                                   @NO, AVLinearPCMIsBigEndianKey,
                                   nil];

    AVAssetWriterInput *assetWriterInput =[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio
                                        outputSettings:outputSettings];
    if ([assetWriter canAddInput:assetWriterInput]) {
        [assetWriter addInput:assetWriterInput];
    } else {
        NSLog (@"can't add asset writer input... die!");
        return;
    }
    assetWriterInput.expectsMediaDataInRealTime = NO;


    [assetWriter startWriting];
    [assetReader startReading];
    AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
    CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
    [assetWriter startSessionAtSourceTime: startTime];


    __block UInt64 convertedByteCount = 0;
    dispatch_queue_t mediaInputQueue =
    dispatch_queue_create("mediaInputQueue", NULL);
    [assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
                                            usingBlock: ^
     {
         while (assetWriterInput.readyForMoreMediaData) {
             CMSampleBufferRef nextBuffer =
             [assetReaderOutput copyNextSampleBuffer];
             if (nextBuffer) {
                 // append buffer
                 [assetWriterInput appendSampleBuffer: nextBuffer];
                 // update ui
                 convertedByteCount +=
                 CMSampleBufferGetTotalSampleSize (nextBuffer);


             } else {
                 // done!
                 [assetWriterInput markAsFinished];
                 [assetWriter finishWritingWithCompletionHandler:^{

                     [assetReader cancelReading];
                     [self performSelectorOnMainThread:@selector(updateCompletedAtMusicPath:)
                                            withObject:exportPath
                                         waitUntilDone:NO];

                   //  NSLog (@"done. file size is %llu",[outputFileAttributes fileSize]);
                 }];
                 break;
             }}}];
    [self dismissViewControllerAnimated:NO completion:^{

    }];
}

这是用于在文档目录

中创建iTune库和故事的URL的代码

答案 1 :(得分:0)

首先,我只想指出您可以通过设置assetReader的timeRange属性来读取库中音频的片段。这样,您可以只复制所需的段,而不是复制整个文件。话虽如此,如果您要坚持原始实现,我认为您只需要将How about Something like the following: SELECT r.Heat ,c.ctemp ,s.ShiftIdent ,r.ChargeSeq ,s.rollLocSeq FROM (NYS1ShiftCut s inner join NYS1CharpyOrders c on c.CharpyOrderID = s.CharpyID) join NYS1Reheat r on r.LocSeq = s.RollLocSeq where c.CTemp < +40 AND r.heat IN (SELECT DISTINCT r.HEAT FROM NYS1ShiftCut s inner join NYS1CharpyOrders c on c.CharpyOrderID = s.CharpyID) join NYS1Reheat r on r.LocSeq = s.RollLocSeq) order by s.rollLocSeq desc 更改为AVURLAsset *assetUrl = [AVURLAsset assetWithURL:audioFileInput];

答案 2 :(得分:0)

我通过使用以下方法

来保存文档库中的itune音乐
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
self.fullPathToFileForAudio = [documentsDirectory stringByAppendingPathComponent:@"auto-old.m4a"];

        NSFileManager *fileMgr = [NSFileManager defaultManager];

        // get rid of existing mp4 if exists...
        if ([fileMgr removeItemAtPath:self.fullPathToFileForAudio error:&error] != YES)
            NSLog(@"Unable to delete file: %@", [error localizedDescription]);


        [self convertVideoToLowQuailtyWithInputURL:self.musicUrl outputURL:[NSURL fileURLWithPath:self.fullPathToFileForAudio] handler:^(AVAssetExportSession *exportSession)
         {
             if (exportSession.status == AVAssetExportSessionStatusCompleted)
             {
                 NSLog(@"completed %@",exportSession.error);

                 printf("completed\n");


                 dispatch_sync(dispatch_get_main_queue(), ^{

                     NSLog(@"%@ PATH",self.fullPathToFileForAudio);
                     [self exporterCompleted:[NSURL fileURLWithPath:self.fullPathToFileForAudio]];
                 });
             }
             else
             {
                 //  NSLog(@"%@",exportSession.error);
                 printf("error\n");

                 dispatch_sync(dispatch_get_main_queue(), ^{
                     [SVProgressHUD dismiss];
                 });

             }
         }];



- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL
                                   outputURL:(NSURL*)outputURL
                                     handler:(void (^)(AVAssetExportSession*))handler
{
    [[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetAppleM4A];

    CMTime startTime = CMTimeMake(minValue, 1);
    CMTime stopTime = CMTimeMake(maxValue, 1);
    CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);

    exportSession.outputURL = outputURL;
    exportSession.outputFileType = @"com.apple.m4a-audio";
    exportSession.timeRange = exportTimeRange;

    [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
     {
         handler(exportSession);

     }];
}