ventajas desventajas descargar caracteristicas ios7 avassetwriter completionhandler

desventajas - El controlador de finalización no se llama en iOS7 GM



ios 9 (5)

Estoy usando AVAssetWriter y funciona perfectamente en iOS6.

El problema es que cuando llamé finishWritingWithCompletionHandler , el controlador de finalización no se llama en iOS7 GM.

Llamé a markAsFinished e incluso endSessionAtSourceTime antes de llamar a finalWritingWithCompletionHandler.

Funciona bien en iOS6.

Y aún más, en iOS7, funciona algunas veces, y luego no vuelve a funcionar.

No sé por qué, pero funciona si llamo al método utilizando la vista de alerta. Así que intenté performSelectorOnMainThread y inBackground , pero no sirvió de nada.

¿Algunas ideas?


Aparentemente necesitas retener el assetWriter ahora.

Puede intentar conservarlo con una propiedad sólida y ver si se llama al controlador de finalización. (Asegúrese de anular esa propiedad en el controlador de finalización).


Esto también sucede en ARC.

La solución más sencilla es definir las propiedades de AVAssetWriter (y AVAssetReader supongo)

@property(nonatomic,strong) AVAssetWriter *assetWriter; @property(nonatomic,strong) AVAssetReader *assetReader;

y entonces

self.assetWriter = [AVAssetWriter assetWriterWithURL:destURL fileType:AVFileTypeWAVE error:&assetError];

y en el bloque de terminación

[assetWriterInput markAsFinished]; [assetWriter finishWritingWithCompletionHandler:^{ [assetReader cancelReading]; completionBlock(self); }];


Ray Fix, tienes razón. Necesitamos retener assetWriter. La forma más fácil es usarlo dentro del bloque finishWritingWithCompletionHandler:

NSError *error = nil; AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:path] fileType:AVFileType3GPP error:&error]; //startWriting, session etc. [videoWriter finishWritingWithCompletionHandler:^{ NSLog(@"%@",videoWriter); NSLog(@"Write Ended"); }];


Retener al asetwriter es muy importante, pero también me encontré con una falla intermitente muy extraña a pesar de que todos los asetwriters fueron retenidos (y nunca reutilizados). El problema tampoco fue una colisión de nombres de archivos o un directorio faltante porque todos mis nombres de archivos se basan en CACurrentMediaTime () y no cambian los directorios.

Parece que si no configura endSessionAtSourceTime: para el assetwriter cada vez, existe una posibilidad muy rara (pero reproducible) de que el controlador de finalización de finishWritingWithCompletionHandler: nunca se llame. Si esperas unos segundos y verificas el estado del assetwriter, estará en el estado AVAssetWriterStatusFailure y el error será un no descriptible "Ocurrió un error desconocido (-12763)". Además, cambiar el formato de archivo para el distribuidor no puede afectar el problema. Por último, este problema es probablemente solo un problema si necesita grabar películas rápidamente una y otra vez (ya que la probabilidad de un fallo es probablemente de 1/15 - 1/20).

Por lo tanto, solo asegúrese de almacenar la marca de tiempo de la presentación de la última muestra que está pasando al assetwriter y de llamar a endSessionAtSourceTime: con ese tiempo de muestra justo antes de llamar a finishWritingWithCompletionHandler: con la finishWritingWithCompletionHandler:


También puede ocurrir si el directorio de destino no existe. En este caso, la escritura funciona bien, pero no se crea ningún archivo y no se llama al bloque.