J'ai un fichier vidéo et un fichier audio. Est-il possible de le fusionner à une vidéo avec un fichier son. Je pense que AVMutableComposition devrait m'aider, mais je ne comprends toujours pas comment. des conseils?Comment ajouter de l'audio à un fichier vidéo sur l'iphone SDK
Répondre
Merci Daniel. Je l'ai compris, c'est facile.
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
}
}
];
Oui, il est possible, voici un extrait de code qui est utilisé pour ajouter de l'audio à une composition existante, je l'ai saisi à partir de pommes exemple de code, vous devriez probablement voir le projet entier, vous le trouverez très utile. est AVEditDemo et vous pouvez le trouver dans le matériel WWDC 2010 qu'ils ont posté ici developer.apple.com/videos/wwdc/2010. Hope qui aide
- (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;
}
Où est cette démo? Je ne peux pas trouver de téléchargement pour ça n'importe où. –
oui ... où est la démo ??? –
Je ne fusionne qu'un seul fichier audio/vidéo. Le problème est que, mon fichier vidéo de 40 secondes et le fichier audio est de 28 secondes. Donc pour rester 12 (40-28) secondes - je veux le répéter de 0 secondes dans le fichier audio. Comment je fais ça? Y a-t-il un moyen direct de faire cela? – Hemang
Voici la version rapide:
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!)
})
})
}
acutually ce morceau de code ne fonctionne pas correctement .. quand j'implémenter ce code dans mon projet alors il sera écrasé sur [compositionCommentaryTrack insertTimeRange: CMTimeRangeMake (kCMTimeZero, audioAsset.duration) ofTrack: [[audioAsset tracksWithMediaType: AVMediaTypeAudio] objectAtIndex: 0] atTime: erreur kCMTimeZero: nulle]; et montre qu'il n'y a aucun objet à l'index zéro .. – Swastik
@Swastik Je rencontre le même problème à l'occasion, en particulier lorsque vous travaillez avec des fichiers de l'iCloud. La solution pour moi a été de faire 2 choses. 1) vérifier que le fichier que j'essaie d'utiliser est valide pour le type de média que j'essaie de l'utiliser et 2) m'assurer que le fichier contient réellement des données (ce qui n'est pas toujours le cas avec iCloud) – nick
hi Steve, je ne fais que fusionner un seul fichier audio/vidéo. Le problème est que, mon fichier vidéo de 40 secondes et le fichier audio est de 28 secondes. Donc pour rester 12 (40-28) secondes - je veux le répéter de 0 secondes dans le fichier audio. Comment je fais ça? Y a-t-il un moyen direct de faire cela? – Hemang