2010-08-09 12 views

Odpowiedz

18

Thanks Daniel. Rozgryzłem to, to łatwe.

AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil]; 
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil]; 

AVMutableComposition* mixComposition = [AVMutableComposition composition]; 

AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio 
                        preferredTrackID:kCMPersistentTrackID_Invalid]; 
[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.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]; 

NSString* videoName = @"export.mov"; 

NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName]; 
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath]; 

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

_assetExport.outputFileType = @"com.apple.quicktime-movie"; 
DLog(@"file type %@",_assetExport.outputFileType); 
_assetExport.outputURL = exportUrl; 
_assetExport.shouldOptimizeForNetworkUse = YES; 

[_assetExport exportAsynchronouslyWithCompletionHandler: 
^(void) {  
      // your completion code here 
    }  
} 
]; 
+0

dokładnie ten kod nie działa poprawnie. Kiedy zaimplementuję ten kod w moim projekcie, nastąpi awaria [compositionCommentaryTrack insertTimeRange: CMTimeRangeMake (kCMTimeZero, audioAsset.duration) ofTrack: [[audioAsset tracksWithMediaType: AVMediaTypeAudio] objectAtIndex: 0] atTime: kCMTimeZero error: nil]; i pokazuje, że nie ma obiektu w indeksie zerowym. – Swastik

+0

@Swastik Występuję na tym samym problemie, czasami, szczególnie podczas pracy z plikami z iCloud. Naprawiono dla mnie 2 rzeczy. 1) sprawdź, czy plik, którego próbuję użyć, jest poprawny dla typu multimediów, z których próbuję go użyć, i 2) upewnij się, że plik rzeczywiście zawiera dane (które czasami nie ma w przypadku iCloud). Cz. – nick

+0

cześć Steve, łączę tylko jeden plik audio/wideo. Problem w tym, że mój plik wideo z 40 sekundami i plikiem audio ma 28 sekund. Więc przez pozostałe 12 (40-28) sekund - chcę powtórzyć od 0 sekund w pliku audio. Jak mam to zrobić? Czy istnieje bezpośredni sposób na zrobienie tego? – Hemang

6

Tak, jest to możliwe, tutaj jest fragment kodu, który jest używany do dodawania dźwięku do istniejącej kompozycji, chwyciłem to z przykładowego kodu jabłka, prawdopodobnie powinieneś zobaczyć cały projekt, uznasz to za bardzo użyteczne, projekt to AVEditDemo i możesz go znaleźć w materiale WWDC 2010, który opublikował tutaj developer.apple.com/videos/wwdc/2010. Nadzieję, że pomoże

- (void)addCommentaryTrackToComposition:(AVMutableComposition *)composition withAudioMix:(AVMutableAudioMix *)audioMix 

{ 

NSInteger i; 

NSArray *tracksToDuck = [composition tracksWithMediaType:AVMediaTypeAudio]; // before we add the commentary 



// Clip commentary duration to composition duration. 

CMTimeRange commentaryTimeRange = CMTimeRangeMake(self.commentaryStartTime, self.commentary.duration); 

if (CMTIME_COMPARE_INLINE(CMTimeRangeGetEnd(commentaryTimeRange), >, [composition duration])) 

    commentaryTimeRange.duration = CMTimeSubtract([composition duration], commentaryTimeRange.start); 



// Add the commentary track. 

AVMutableCompositionTrack *compositionCommentaryTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, commentaryTimeRange.duration) ofTrack:[[self.commentary tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:commentaryTimeRange.start error:nil]; 





NSMutableArray *trackMixArray = [NSMutableArray array]; 

CMTime rampDuration = CMTimeMake(1, 2); // half-second ramps 

for (i = 0; i < [tracksToDuck count]; i++) { 

    AVMutableAudioMixInputParameters *trackMix = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:[tracksToDuck objectAtIndex:i]]; 

    [trackMix setVolumeRampFromStartVolume:1.0 toEndVolume:0.2 timeRange:CMTimeRangeMake(CMTimeSubtract(commentaryTimeRange.start, rampDuration), rampDuration)]; 

    [trackMix setVolumeRampFromStartVolume:0.2 toEndVolume:1.0 timeRange:CMTimeRangeMake(CMTimeRangeGetEnd(commentaryTimeRange), rampDuration)]; 

    [trackMixArray addObject:trackMix]; 

} 

audioMix.inputParameters = trackMixArray; 

}

+1

Gdzie jest to demo? Nie mogę znaleźć do pobrania dla niego w dowolnym miejscu. –

+0

tak ... gdzie jest wersja demonstracyjna ??? –

+0

Łączę tylko jeden plik audio/wideo. Problem w tym, że mój plik wideo z 40 sekundami i plikiem audio ma 28 sekund. Więc przez pozostałe 12 (40-28) sekund - chcę powtórzyć od 0 sekund w pliku audio. Jak mam to zrobić? Czy istnieje bezpośredni sposób na zrobienie tego? – Hemang

0

Oto szybka wersja:

func mixAudio(audioURL audioURL: NSURL, videoURL: NSURL) { 
    let audioAsset = AVURLAsset(URL: audioURL) 
    let videoAsset = AVURLAsset(URL: videoURL) 

    let mixComposition = AVMutableComposition() 

    let compositionCommentaryTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) 

    // add audio 
    let timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration) 
    let track = audioAsset.tracksWithMediaType(AVMediaTypeAudio)[0] 
    do { 
     try compositionCommentaryTrack.insertTimeRange(timeRange, ofTrack: track, atTime: kCMTimeZero) 
    } 
    catch { 
     print("Error insertTimeRange for audio track \(error)") 
    } 

    // add video 
    let compositionVideoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) 

    let timeRangeVideo = CMTimeRangeMake(kCMTimeZero, videoAsset.duration) 
    let trackVideo = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] 
    do { 
     try compositionVideoTrack.insertTimeRange(timeRangeVideo, ofTrack: trackVideo, atTime: kCMTimeZero) 
    } 
    catch { 
     print("Error insertTimeRange for video track \(error)") 
    } 

    // export 
    let assetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetPassthrough) 
    let videoName = "export.mov" 
    exportPath = "\(NSTemporaryDirectory())/\(videoName)" 
    let exportURL = NSURL(fileURLWithPath: exportPath!) 

    if NSFileManager.defaultManager().fileExistsAtPath(exportPath!) { 
     do { 
      try NSFileManager.defaultManager().removeItemAtPath(exportPath!) 
     } 
     catch { 
      print("Error deleting export.mov: \(error)") 
     } 
    } 

    assetExportSession?.outputFileType = "com.apple.quicktime-movie" 
    assetExportSession?.outputURL = exportURL 
    assetExportSession?.shouldOptimizeForNetworkUse = true 
    assetExportSession?.exportAsynchronouslyWithCompletionHandler({ 
     print("Mixed audio and video!") 
     dispatch_async(dispatch_get_main_queue(), { 
      print(self.exportPath!) 

     }) 
    }) 

} 
Powiązane problemy