2012-12-21 6 views
4

J'essaie de lire une vidéo image par image à partir d'un album photo iPhone. Après le traitement de l'image, je vais les enregistrer en tant que nouvelle vidéo. Je cours mon code sans erreur, mais il n'y a pas de nouvelle vidéo dans l'album.iOS - Lire un fichier vidéo image par image, traitement d'image, puis enregistrer en tant que nouveau fichier vidéo

Voici mon code.

// Video writer init 
- (BOOL)setupAssetWriterForURL:(CMFormatDescriptionRef)formatDescription 
{ 
    float bitsPerPixel; 
    CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription); 
    int numPixels = dimensions.width * dimensions.height; 
    int bitsPerSecond; 

    if (numPixels < (640 * 480)) 
     bitsPerPixel = 4.05; 
    else 
     bitsPerPixel = 11.4; 

    bitsPerSecond = numPixels * bitsPerPixel; 

    NSDictionary *videoCompressionSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
               AVVideoCodecH264, AVVideoCodecKey, 
               [NSNumber numberWithInteger:dimensions.width], AVVideoWidthKey, 
               [NSNumber numberWithInteger:dimensions.height], AVVideoHeightKey, 
               [NSDictionary dictionaryWithObjectsAndKeys: 
               [NSNumber numberWithInteger:bitsPerSecond], AVVideoAverageBitRateKey, 
               [NSNumber numberWithInteger:30], AVVideoMaxKeyFrameIntervalKey, 
               nil], AVVideoCompressionPropertiesKey, 
               nil]; 
    if ([assetWriter canApplyOutputSettings:videoCompressionSettings forMediaType:AVMediaTypeVideo]) { 
     assetWriterVideoIn = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoCompressionSettings]; 
     assetWriterVideoIn.expectsMediaDataInRealTime = YES; 
     assetWriterVideoIn.transform = [self transformFromCurrentVideoOrientationToOrientation:self.referenceOrientation]; 
     if ([assetWriter canAddInput:assetWriterVideoIn]) 
      [assetWriter addInput:assetWriterVideoIn]; 
     else { 
      NSLog(@"Couldn't add asset writer video input."); 
      return NO; 
     } 
    } 
    else { 
     NSLog(@"Couldn't apply video output settings."); 
     return NO; 
    } 

    return YES; 
} 

Lire vidéo

- (void)readMovie:(NSURL *)url 
{ 
    AVURLAsset * asset = [AVURLAsset URLAssetWithURL:url options:nil]; 
    [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler: 
    ^{ 
     dispatch_async(dispatch_get_main_queue(), 
         ^{ 
          AVAssetTrack * videoTrack = nil; 
          NSArray * tracks = [asset tracksWithMediaType:AVMediaTypeVideo]; 
          if ([tracks count] == 1) 
          { 
           videoTrack = [tracks objectAtIndex:0]; 

           NSError * error = nil; 

           // _movieReader is a member variable 
           AVAssetReader *movieReader = [[AVAssetReader alloc] initWithAsset:asset error:&error]; 
           if (error) 
            NSLog(@"_movieReader fail!\n"); 

           NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
           NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
           NSDictionary* videoSettings = 
           [NSDictionary dictionaryWithObject:value forKey:key]; 

           [movieReader addOutput:[AVAssetReaderTrackOutput 
                 assetReaderTrackOutputWithTrack:videoTrack 
                 outputSettings:videoSettings]]; 
           [movieReader startReading]; 

           while ([movieReader status] == AVAssetReaderStatusReading) 
           { 
            AVAssetReaderTrackOutput * output = [movieReader.outputs objectAtIndex:0]; 
            CMSampleBufferRef sampleBuffer = [output copyNextSampleBuffer]; 
            if (sampleBuffer) 
            { 
             if (!assetWriter) { 
              outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%llu.mov", NSTemporaryDirectory(), mach_absolute_time()]]; 

              NSError *error = nil; 
              assetWriter = [[AVAssetWriter alloc] initWithURL:outputURL fileType:(NSString *)kUTTypeQuickTimeMovie error:&error]; 
              if (error) 
               [self showError:error]; 


              if (assetWriter) { 
               CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer); 
               [self setupAssetWriterForURL:formatDescription]; 
              } 
             } 
             CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 


             CVPixelBufferLockBaseAddress(imageBuffer,0); 

             int bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
             int bufferWidth = CVPixelBufferGetWidth(imageBuffer); 
             int bufferHeight = CVPixelBufferGetHeight(imageBuffer); 
             unsigned char *pixel = (unsigned char *)CVPixelBufferGetBaseAddress(imageBuffer); 


             for(int row = 0; row < bufferHeight; row++) { 
              for(int column = 0; column < bufferWidth; column++) { 

               pixel[0] = (pixel[0]+pixel[1]+pixel[2])/3; 
               pixel[1] = (pixel[0]+pixel[1]+pixel[2])/3; 
               pixel[2] = (pixel[0]+pixel[1]+pixel[2])/3; 

               pixel += 4; 
              } 
             } 


             CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

             if (assetWriter) { 
              [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeVideo]; 
             } 


             CFRelease(sampleBuffer); 
            } 

           } 
           if (assetWriter) { 
            [assetWriterVideoIn markAsFinished]; 
            assetWriter = nil; 
            [assetWriter finishWriting]; 
            assetWriterVideoIn = nil; 
            assetWriter = nil; 

            [self saveMovieToCameraRoll]; 
           } 
           else { 
            [self showError:[assetWriter error]]; 
           } 

          } 
         }); 
    }]; 

} 
- (void) writeSampleBuffer:(CMSampleBufferRef)sampleBuffer ofType:(NSString *)mediaType 
{ 
    if (assetWriter.status == AVAssetWriterStatusUnknown) { 

     if ([assetWriter startWriting]) { 
      [assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)]; 
     } 
     else { 
      [self showError:[assetWriter error]]; 
     } 
    } 

    if (assetWriter.status == AVAssetWriterStatusWriting) { 

     if (mediaType == AVMediaTypeVideo) { 
      if (assetWriterVideoIn.readyForMoreMediaData) { 
       if (![assetWriterVideoIn appendSampleBuffer:sampleBuffer]) { 
        [self showError:[assetWriter error]]; 
       } 
      } 
     } 

    } 
} 
- (void)saveMovieToCameraRoll 
{ 
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
    [library writeVideoAtPathToSavedPhotosAlbum:outputURL 
           completionBlock:^(NSURL *assetURL, NSError *error) { 
            if (error){ 
             [self showError:error]; 
            NSLog(@"save fail"); 
           } 
            else 
            { 
             [self removeFile:outputURL]; 
             NSLog(@"!!!"); 
            } 
            }); 
           }]; 
} 
- (void)removeFile:(NSURL *)fileURL 
{ 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSString *filePath = [fileURL path]; 
    if ([fileManager fileExistsAtPath:filePath]) { 
     NSError *error; 
     BOOL success = [fileManager removeItemAtPath:filePath error:&error]; 
     if (!success) 
      [self showError:error]; 
    } 
} 

Toutes les suggestions?

+0

Bienvenue sur Stack Overflow! Avez-vous essayé quelque chose de spécifique pour résoudre votre problème? – asteri

+0

Je vois où est le problème. L'horodatage est incorrect. –

Répondre

1

Et Here est une réponse pour la création de film à partir d'images.

Espérons que vous obtiendrez de l'aide à partir de là.

+0

Je pense que stopNgo caméra qui est sur le site de développeur Apple si vous avez une idée montre ce que vous essayez de faire. Il combine des images dans un film rapide. –

+0

Merci beaucoup. J'examine stopNgo encore, alors le problème est résolu. –

3

Je suis un peu en retard, mais il pourrait être utile pour les autres que le code est presque droit, mais simplement commenter une ligne de code, il fonctionnera, qui est en readMovie: méthode

      //assetWriter = nil; commented line 
           [assetWriter finishWriting]; 
           assetWriterVideoIn = nil; 
           assetWriter = nil; 

           [self saveMovieToCameraRoll]; 
          }` 
Questions connexes