iOS Audio Trimming

前端 未结 4 1898
既然无缘
既然无缘 2020-11-28 05:08

I searched a lot and couldn\'t find anything relevant... I am working on iOS audio files and here is what I want to do...

  1. Record Audio and Save Clip (Checked,
相关标签:
4条回答
  • 2020-11-28 05:41

    // Swift 4.2

    If anybody is still looking for answer in swift here it is.

    //Audio Trimming

    func trimAudio(asset: AVAsset, startTime: Double, stopTime: Double, finished:@escaping (URL) -> ())
    {
    
            let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith:asset)
    
            if compatiblePresets.contains(AVAssetExportPresetMediumQuality) {
    
            guard let exportSession = AVAssetExportSession(asset: asset, 
            presetName: AVAssetExportPresetAppleM4A) else{return}
    
            // Creating new output File url and removing it if already exists.
            let furl = createUrlInAppDD("trimmedAudio.m4a") //Custom Function
            removeFileIfExists(fileURL: furl) //Custom Function
    
            exportSession.outputURL = furl
            exportSession.outputFileType = AVFileType.m4a
    
            let start: CMTime = CMTimeMakeWithSeconds(startTime, preferredTimescale: asset.duration.timescale)
            let stop: CMTime = CMTimeMakeWithSeconds(stopTime, preferredTimescale: asset.duration.timescale)
            let range: CMTimeRange = CMTimeRangeFromTimeToTime(start: start, end: stop)
            exportSession.timeRange = range
    
            exportSession.exportAsynchronously(completionHandler: {
    
                switch exportSession.status {
                case .failed:
                    print("Export failed: \(exportSession.error!.localizedDescription)")
                case .cancelled:
                    print("Export canceled")
                default:
                    print("Successfully trimmed audio")
                    DispatchQueue.main.async(execute: {
                        finished(furl)
                    })
                }
            })
        }
    }
    

    You can use it for video trimming as well. For Video trimming replace the value of export session as bellow:

    guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else{return}

    and filetype to mp4

    exportSession.outputFileType = AVFileType.mp4

    0 讨论(0)
  • 2020-11-28 05:50

    Here is a sample code which trim audio file from starting & ending offset and save it back. Please check this iOS Audio Trimming.

    // Path of your source audio file
    NSString *strInputFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"abc.mp3"];
    NSURL *audioFileInput = [NSURL fileURLWithPath:strInputFilePath];
    
    // Path of your destination save audio file
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
        NSString *libraryCachesDirectory = [paths objectAtIndex:0];
        libraryCachesDirectory = [libraryCachesDirectory stringByAppendingPathComponent:@"Caches"];
    
    NSString *strOutputFilePath = [NSString stringWithFormat:@"%@%@",libraryCachesDirectory,@"/abc.mp4"];
    NSURL *audioFileOutput = [NSURL fileURLWithPath:strOutputFilePath];
    
    if (!audioFileInput || !audioFileOutput)
    {
        return NO;
    }
    
    [[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
    AVAsset *asset = [AVAsset assetWithURL:audioFileInput];
    
    AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetAppleM4A];
    
    if (exportSession == nil)
    {
        return NO;
    }
    float startTrimTime = 0; 
    float endTrimTime = 5;
    
    CMTime startTime = CMTimeMake((int)(floor(startTrimTime * 100)), 100);
    CMTime stopTime = CMTimeMake((int)(ceil(endTrimTime * 100)), 100);
    CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
    
    exportSession.outputURL = audioFileOutput;
    exportSession.outputFileType = AVFileTypeAppleM4A;
    exportSession.timeRange = exportTimeRange;
    
    [exportSession exportAsynchronouslyWithCompletionHandler:^
    {
        if (AVAssetExportSessionStatusCompleted == exportSession.status)
        {
            NSLog(@"Success!");
        }
        else if (AVAssetExportSessionStatusFailed == exportSession.status)
        {
            NSLog(@"failed");
        }
    }];
    
    0 讨论(0)
  • 2020-11-28 05:54

    import following two libraries in .m

    #import "BJRangeSliderWithProgress.h"
    #import  < AVFoundation/AVFoundation.h >
    

    and after that paste following code you will be able to trim an audio file with the help of two thumbs.

    - (void) viewDidLoad
    {
          [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.
    
           mySlider = [[BJRangeSliderWithProgress alloc] initWithFrame:CGRectMake(20, 100, 300, 50)];
    
          [mySlider setDisplayMode:BJRSWPAudioSetTrimMode];
    
          [mySlider addTarget:self action:@selector(valueChanged) forControlEvents:UIControlEventValueChanged];
    
          [mySlider setMinValue:0.0];
    
          NSString *strInputFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"saewill.mp3"];
    
          NSURL *audioFileInput = [NSURL fileURLWithPath:strInputFilePath];
    
          audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:audioFileInput error:nil];
    
          [mySlider setMaxValue:audioPlayer.duration];
    
          [self.view addSubview:mySlider];
    }
    
    -(void)valueChanged {
          NSLog(@"%f %f", mySlider.leftValue, mySlider.rightValue);
    }
    
    
    -(IBAction)playTheSong
    {
          // Path of your source audio file
          NSString *strInputFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"saewill.mp3"];
          NSURL *audioFileInput = [NSURL fileURLWithPath:strInputFilePath];
    
          // Path of your destination save audio file
          NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
          NSString *libraryCachesDirectory = [paths objectAtIndex:0];
          //libraryCachesDirectory = [libraryCachesDirectory stringByAppendingPathComponent:@"Caches"];
    
          NSString *strOutputFilePath = [libraryCachesDirectory stringByAppendingPathComponent:@"output.mov"];
          NSString *requiredOutputPath = [libraryCachesDirectory stringByAppendingPathComponent:@"output.m4a"];
          NSURL *audioFileOutput = [NSURL fileURLWithPath:requiredOutputPath];
    
          [[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
          AVAsset *asset = [AVAsset assetWithURL:audioFileInput];
    
          AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset
                                                                                  presetName:AVAssetExportPresetAppleM4A];
    
    
          float startTrimTime = mySlider.leftValue;
          float endTrimTime = mySlider.rightValue;
    
          CMTime startTime = CMTimeMake((int)(floor(startTrimTime * 100)), 100);
          CMTime stopTime = CMTimeMake((int)(ceil(endTrimTime * 100)), 100);
          CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
    
          exportSession.outputURL = audioFileOutput;
          exportSession.outputFileType = AVFileTypeAppleM4A;
          exportSession.timeRange = exportTimeRange;
    
          [exportSession exportAsynchronouslyWithCompletionHandler:^
           {
               if (AVAssetExportSessionStatusCompleted == exportSession.status)
               {
                   NSLog(@"Success!");
                   NSLog(@" OUtput path is \n %@", requiredOutputPath);
                   NSFileManager * fm = [[NSFileManager alloc] init];
                   [fm moveItemAtPath:strOutputFilePath toPath:requiredOutputPath error:nil];
                   //[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
    
                   NSURL *url=[NSURL fileURLWithPath:requiredOutputPath];
                   NSError *error;
                   audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
                   audioPlayer.numberOfLoops=0;
                   [audioPlayer play];
    
               }
               else if (AVAssetExportSessionStatusFailed == exportSession.status)
               {
                   NSLog(@"failed with error: %@", exportSession.error.localizedDescription);
               }
           }];
    
    }
    
    0 讨论(0)
  • 2020-11-28 06:04

    Here's the code that I've used to trim audio from a pre-existing file. You'll need to change the M4A related constants if you've saved or are saving to another format.

    - (BOOL)trimAudio
    {
        float vocalStartMarker = <starting time>;
        float vocalEndMarker = <ending time>;
    
        NSURL *audioFileInput = <your pre-existing file>;
        NSURL *audioFileOutput = <the file you want to create>;
    
        if (!audioFileInput || !audioFileOutput)
        {
            return NO;
        }
    
        [[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
        AVAsset *asset = [AVAsset assetWithURL:audioFileInput];
    
        AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset
                                                                                presetName:AVAssetExportPresetAppleM4A];
    
        if (exportSession == nil)
        {        
            return NO;
        }
    
        CMTime startTime = CMTimeMake((int)(floor(vocalStartMarker * 100)), 100);
        CMTime stopTime = CMTimeMake((int)(ceil(vocalEndMarker * 100)), 100);
        CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
    
        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;
    }
    

    There's also Technical Q&A 1730, which gives a slightly more detailed approach.

    0 讨论(0)
提交回复
热议问题