Example #1
0
        public void StartWithAsync(TaskCompletionSource <object> completionSource, AVReaderWriter handler)
        {
            if (_completionSource != null)
            {
                throw new InvalidProgramException();
            }

            _completionSource = completionSource;

            _assetWriterInput.RequestMediaData(_serializationQueue, () => {
                if (_finished)
                {
                    return;
                }

                bool completedOrFailed = false;

                // Read samples in a loop as long as the asset writer input is ready
                while (_assetWriterInput.ReadyForMoreMediaData && !completedOrFailed)
                {
                    bool success;
                    using (CMSampleBuffer sampleBuffer = _assetReaderOutput.CopyNextSampleBuffer()) {
                        if (sampleBuffer == null)
                        {
                            completedOrFailed = true;
                            continue;
                        }

                        if (_adaptor != null)
                        {
                            CMTime presentationTime = sampleBuffer.PresentationTimeStamp;
                            using (CVPixelBuffer writerBuffer = _adaptor.PixelBufferPool.CreatePixelBuffer()) {
                                handler.DidReadAndWriteSampleBuffer(this, sampleBuffer, writerBuffer);
                                success = _adaptor.AppendPixelBufferWithPresentationTime(writerBuffer, presentationTime);
                            }
                        }
                        else
                        {
                            handler.DidReadSampleBuffer(this, sampleBuffer);
                            success = _assetWriterInput.AppendSampleBuffer(sampleBuffer);
                        }
                    }
                    completedOrFailed = !success;
                }

                if (completedOrFailed)
                {
                    CompleteTaskIfNecessary();
                }
            });
        }
        // TODO: where called in original sample
        // - (void)cancel:(id)sender

        private Task StartReadingAsync(ReadWriteSampleBufferChannel channel, AVReaderWriter handler)
        {
            var completionSrc = new TaskCompletionSource <object> ();

            if (channel == null)
            {
                completionSrc.SetResult(null);
            }
            else
            {
                channel.StartWithAsync(completionSrc, handler);
            }

            return(completionSrc.Task);
        }
        public void DidReadSampleBuffer(ReadWriteSampleBufferChannel sampleBufferChannel, CMSampleBuffer sampleBuffer)
        {
            // Calculate progress (scale of 0.0 to 1.0)
            double progress = AVReaderWriter.ProgressOfSampleBufferInTimeRange(sampleBuffer, _timeRange);

            _progressProc((float)progress * 100);

            // Grab the pixel buffer from the sample buffer, if possible
            CVImageBuffer imageBuffer = sampleBuffer.GetImageBuffer();

            var pixelBuffer = imageBuffer as CVPixelBuffer;

            if (pixelBuffer != null)
            {
                Delegate.AdjustPixelBuffer(pixelBuffer, null);                  // TODO: problem in original sample. No method
            }
        }
        Task FinishVideoEditing(Action <PHContentEditingOutput> completionHandler)
        {
            PHContentEditingOutput contentEditingOutput = CreateOutput();
            AVReaderWriter         avReaderWriter       = new AVReaderWriter(contentEditingInput.AvAsset, this);

            var tcs = new TaskCompletionSource <object> ();

            // Save filtered video
            avReaderWriter.WriteToUrl(contentEditingOutput.RenderedContentUrl, error => {
                bool success = error == null;
                PHContentEditingOutput output = success ? contentEditingOutput : null;
                if (!success)
                {
                    Console.WriteLine("An error occured: {0}", error);
                }
                completionHandler(output);
                tcs.SetResult(null);                  // inform that we may safely clean up any data
            });

            return(tcs.Task);
        }
		public void StartWithAsync (TaskCompletionSource<object> completionSource, AVReaderWriter handler)
		{
			if (_completionSource != null)
				throw new InvalidProgramException ();

			_completionSource = completionSource;

			_assetWriterInput.RequestMediaData (_serializationQueue, () => {
				if (_finished)
					return;

				bool completedOrFailed = false;

				// Read samples in a loop as long as the asset writer input is ready
				while (_assetWriterInput.ReadyForMoreMediaData && !completedOrFailed) {
					bool success;
					using (CMSampleBuffer sampleBuffer = _assetReaderOutput.CopyNextSampleBuffer ()) {
						if (sampleBuffer == null) {
							completedOrFailed = true;
							continue;
						}

						if (_adaptor != null) {
							CMTime presentationTime = sampleBuffer.PresentationTimeStamp;
							using (CVPixelBuffer writerBuffer = _adaptor.PixelBufferPool.CreatePixelBuffer ()) {
								handler.DidReadAndWriteSampleBuffer (this, sampleBuffer, writerBuffer);
								success = _adaptor.AppendPixelBufferWithPresentationTime (writerBuffer, presentationTime);
							}
						} else {
							handler.DidReadSampleBuffer (this, sampleBuffer);
							success = _assetWriterInput.AppendSampleBuffer (sampleBuffer);
						}
					}
					completedOrFailed = !success;
				}

				if (completedOrFailed)
					CompleteTaskIfNecessary ();
			});
		}
        private void StartReadingAndWriting()
        {
            // Instruct the asset reader and asset writer to get ready to do work
            if (!_assetReader.StartReading())
            {
                throw new NSErrorException(_assetReader.Error);
            }

            if (!_assetWriter.StartWriting())
            {
                throw new NSErrorException(_assetWriter.Error);
            }

            // Start a sample-writing session
            _assetWriter.StartSessionAtSourceTime(_timeRange.Start);

            // Only set audio handler(obj-c delegate) for audio-only assets, else let the video channel drive progress
            AVReaderWriter audioHandler = _videoSampleBufferChannel == null ? this : null;
            var            audioTask    = StartReadingAsync(_audioSampleBufferChannel, audioHandler);
            var            videoTask    = StartReadingAsync(_videoSampleBufferChannel, this);

            // Set up a callback for when the sample writing is finished
            Task.WhenAll(audioTask, videoTask).ContinueWith(_ => {
                if (_cancellationTokenSrc.Token.IsCancellationRequested)
                {
                    _assetReader.CancelReading();
                    _assetWriter.CancelWriting();
                    throw new OperationCanceledException();
                }

                if (_assetReader.Status != AVAssetReaderStatus.Failed)
                {
                    _assetWriter.FinishWriting(() => {
                        bool success = _assetWriter.Status == AVAssetWriterStatus.Completed;
                        ReadingAndWritingDidFinish(success, _assetWriter.Error);
                    });
                }
            }, _cancellationTokenSrc.Token);
        }
        Task FinishVideoEditing(Action<PHContentEditingOutput> completionHandler)
        {
            PHContentEditingOutput contentEditingOutput = CreateOutput ();
            AVReaderWriter avReaderWriter = new AVReaderWriter (contentEditingInput.AvAsset, this);

            var tcs = new TaskCompletionSource<object> ();
            // Save filtered video
            avReaderWriter.WriteToUrl (contentEditingOutput.RenderedContentUrl, error => {
                bool success = error == null;
                PHContentEditingOutput output = success ? contentEditingOutput : null;
                if(!success)
                    Console.WriteLine ("An error occured: {0}", error);
                completionHandler (output);
                tcs.SetResult(null);  // inform that we may safely clean up any data
            });

            return tcs.Task;
        }
		public void FinishContentEditing (Action<PHContentEditingOutput> completionHandler)
		{
			PHContentEditingOutput contentEditingOutput = new PHContentEditingOutput (contentEditingInput);

			// Adjustment data
			NSData archivedData = NSKeyedArchiver.ArchivedDataWithRootObject ((NSString)selectedFilterName);
			PHAdjustmentData adjustmentData = new PHAdjustmentData ("com.your-company.PhotoFilter", "1.0",
				                                  archivedData);
			contentEditingOutput.AdjustmentData = adjustmentData;

			switch (contentEditingInput.MediaType) {
			case PHAssetMediaType.Image:
				{
					// Get full size image
					NSUrl url = contentEditingInput.FullSizeImageUrl;
					CIImageOrientation orientation = contentEditingInput.FullSizeImageOrientation;

					// Generate rendered JPEG data
					UIImage image = UIImage.FromFile (url.Path);
					image = TransformeImage (image, orientation);
					NSData renderedJPEGData = image.AsJPEG (0.9f);

					// Save JPEG data
					NSError error = null;
					bool success = renderedJPEGData.Save (contentEditingOutput.RenderedContentUrl, NSDataWritingOptions.Atomic, out error);
					if (success) {
						completionHandler (contentEditingOutput);
					} else {
						Console.WriteLine ("An error occured: {0}", error);
						completionHandler (null);
					}
					break;
				}

			case PHAssetMediaType.Video:
				{
					// Get AV asset
					AVReaderWriter avReaderWriter = new AVReaderWriter (contentEditingInput.AvAsset);
					avReaderWriter.Delegate = this;

					// Save filtered video
					avReaderWriter.WriteToUrl (contentEditingOutput.RenderedContentUrl,
						progress => {
						},
						error => {
							if (error == null) {
								completionHandler (contentEditingOutput);
								return;
							}
							Console.WriteLine ("An error occured: {0}", error);
							completionHandler (null);
						});
					break;
				}

			default:
				break;
			}
		}
        public void FinishContentEditing(Action <PHContentEditingOutput> completionHandler)
        {
            PHContentEditingOutput contentEditingOutput = new PHContentEditingOutput(contentEditingInput);

            // Adjustment data
            NSData           archivedData   = NSKeyedArchiver.ArchivedDataWithRootObject((NSString)selectedFilterName);
            PHAdjustmentData adjustmentData = new PHAdjustmentData("com.your-company.PhotoFilter", "1.0",
                                                                   archivedData);

            contentEditingOutput.AdjustmentData = adjustmentData;

            switch (contentEditingInput.MediaType)
            {
            case PHAssetMediaType.Image:
            {
                // Get full size image
                NSUrl url = contentEditingInput.FullSizeImageUrl;
                CIImageOrientation orientation = contentEditingInput.FullSizeImageOrientation;

                // Generate rendered JPEG data
                UIImage image = UIImage.FromFile(url.Path);
                image = TransformeImage(image, orientation);
                NSData renderedJPEGData = image.AsJPEG(0.9f);

                // Save JPEG data
                NSError error   = null;
                bool    success = renderedJPEGData.Save(contentEditingOutput.RenderedContentUrl, NSDataWritingOptions.Atomic, out error);
                if (success)
                {
                    completionHandler(contentEditingOutput);
                }
                else
                {
                    Console.WriteLine("An error occured: {0}", error);
                    completionHandler(null);
                }
                break;
            }

            case PHAssetMediaType.Video:
            {
                // Get AV asset
                AVReaderWriter avReaderWriter = new AVReaderWriter(contentEditingInput.AvAsset);
                avReaderWriter.Delegate = this;

                // Save filtered video
                avReaderWriter.WriteToUrl(contentEditingOutput.RenderedContentUrl,
                                          progress => {
                    },
                                          error => {
                        if (error == null)
                        {
                            completionHandler(contentEditingOutput);
                            return;
                        }
                        Console.WriteLine("An error occured: {0}", error);
                        completionHandler(null);
                    });
                break;
            }

            default:
                break;
            }
        }
		// TODO: where called in original sample
		// - (void)cancel:(id)sender

		private Task StartReadingAsync(ReadWriteSampleBufferChannel channel, AVReaderWriter handler)
		{
			var completionSrc = new TaskCompletionSource<object> ();

			if (channel == null)
				completionSrc.SetResult (null);
			else
				channel.StartWithAsync (completionSrc, handler);

			return completionSrc.Task;
		}