এখানে উদ্দেশ্য 8-এ iOS8- এ সর্বশেষতম কোড রয়েছে in
এক্সকোড এবং আইওএস 8 এর সর্বশেষতম সংস্করণে এটি কাজ করতে আমাদের উপরের @ জোলের উত্তরে বিভিন্ন ধরণের টুইট করতে হয়েছিল। এখানে আমাদের সম্পূর্ণ কার্যকারী কোড যা ইউআইআইমেজেজের একটি অ্যারে নেয়, তাদের একটি। এমওভি ফাইল হিসাবে তৈরি করে, এটি একটি অস্থায়ী ডিরেক্টরিতে সংরক্ষণ করে, তারপরে এটি ক্যামেরার রোলে স্থানান্তরিত করে। আমরা এই কাজ পেতে একাধিক বিভিন্ন পোস্ট থেকে কোড একত্রিত। কোডটি আমাদের মন্তব্যে কাজ করার জন্য আমাদের যে ট্র্যাপগুলি সমাধান করতে হয়েছিল তা হাইলাইট করেছি।
(1) ইউআইআইমেজেসের সংগ্রহ তৈরি করুন
[self saveMovieToLibrary]
- (IBAction)saveMovieToLibrary
{
// You just need the height and width of the video here
// For us, our input and output video was 640 height x 480 width
// which is what we get from the iOS front camera
ATHSingleton *singleton = [ATHSingleton singletons];
int height = singleton.screenHeight;
int width = singleton.screenWidth;
// You can save a .mov or a .mp4 file
//NSString *fileNameOut = @"temp.mp4";
NSString *fileNameOut = @"temp.mov";
// We chose to save in the tmp/ directory on the device initially
NSString *directoryOut = @"tmp/";
NSString *outFile = [NSString stringWithFormat:@"%@%@",directoryOut,fileNameOut];
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:outFile]];
NSURL *videoTempURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@%@", NSTemporaryDirectory(), fileNameOut]];
// WARNING: AVAssetWriter does not overwrite files for us, so remove the destination file if it already exists
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:[videoTempURL path] error:NULL];
// Create your own array of UIImages
NSMutableArray *images = [NSMutableArray array];
for (int i=0; i<singleton.numberOfScreenshots; i++)
{
// This was our routine that returned a UIImage. Just use your own.
UIImage *image =[self uiimageFromCopyOfPixelBuffersUsingIndex:i];
// We used a routine to write text onto every image
// so we could validate the images were actually being written when testing. This was it below.
image = [self writeToImage:image Text:[NSString stringWithFormat:@"%i",i ]];
[images addObject:image];
}
// If you just want to manually add a few images - here is code you can uncomment
// NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/movie.mp4"]];
// NSArray *images = [[NSArray alloc] initWithObjects:
// [UIImage imageNamed:@"add_ar.png"],
// [UIImage imageNamed:@"add_ja.png"],
// [UIImage imageNamed:@"add_ru.png"],
// [UIImage imageNamed:@"add_ru.png"],
// [UIImage imageNamed:@"add_ar.png"],
// [UIImage imageNamed:@"add_ja.png"],
// [UIImage imageNamed:@"add_ru.png"],
// [UIImage imageNamed:@"add_ar.png"],
// [UIImage imageNamed:@"add_en.png"], nil];
[self writeImageAsMovie:images toPath:path size:CGSizeMake(height, width)];
}
এটিই হ'ল প্রধান পদ্ধতি যা আপনার সম্পদ রচয়িতা তৈরি করে এবং লেখার জন্য এতে চিত্র যুক্ত করে।
(2) একটি AVAssetWriter তারের আপ
-(void)writeImageAsMovie:(NSArray *)array toPath:(NSString*)path size:(CGSize)size
{
NSError *error = nil;
// FIRST, start up an AVAssetWriter instance to write your video
// Give it a destination path (for us: tmp/temp.mov)
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:path]
fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(videoWriter);
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:size.width], AVVideoWidthKey,
[NSNumber numberWithInt:size.height], AVVideoHeightKey,
nil];
AVAssetWriterInput* writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:nil];
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
(3) একটি লিখন সেশন শুরু করুন (দ্রষ্টব্য: পদ্ধতিটি উপরে থেকে অব্যাহত রয়েছে)
//Start a SESSION of writing.
// After you start a session, you will keep adding image frames
// until you are complete - then you will tell it you are done.
[videoWriter startWriting];
// This starts your video at time = 0
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CVPixelBufferRef buffer = NULL;
// This was just our utility class to get screen sizes etc.
ATHSingleton *singleton = [ATHSingleton singletons];
int i = 0;
while (1)
{
// Check if the writer is ready for more data, if not, just wait
if(writerInput.readyForMoreMediaData){
CMTime frameTime = CMTimeMake(150, 600);
// CMTime = Value and Timescale.
// Timescale = the number of tics per second you want
// Value is the number of tics
// For us - each frame we add will be 1/4th of a second
// Apple recommend 600 tics per second for video because it is a
// multiple of the standard video rates 24, 30, 60 fps etc.
CMTime lastTime=CMTimeMake(i*150, 600);
CMTime presentTime=CMTimeAdd(lastTime, frameTime);
if (i == 0) {presentTime = CMTimeMake(0, 600);}
// This ensures the first frame starts at 0.
if (i >= [array count])
{
buffer = NULL;
}
else
{
// This command grabs the next UIImage and converts it to a CGImage
buffer = [self pixelBufferFromCGImage:[[array objectAtIndex:i] CGImage]];
}
if (buffer)
{
// Give the CGImage to the AVAssetWriter to add to your video
[adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
i++;
}
else
{
(4) অধিবেশন শেষ করুন (দ্রষ্টব্য: পদ্ধতিটি উপরে থেকে অবিরত থাকে)
//Finish the session:
// This is important to be done exactly in this order
[writerInput markAsFinished];
// WARNING: finishWriting in the solution above is deprecated.
// You now need to give a completion handler.
[videoWriter finishWritingWithCompletionHandler:^{
NSLog(@"Finished writing...checking completion status...");
if (videoWriter.status != AVAssetWriterStatusFailed && videoWriter.status == AVAssetWriterStatusCompleted)
{
NSLog(@"Video writing succeeded.");
// Move video to camera roll
// NOTE: You cannot write directly to the camera roll.
// You must first write to an iOS directory then move it!
NSURL *videoTempURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@", path]];
[self saveToCameraRoll:videoTempURL];
} else
{
NSLog(@"Video writing failed: %@", videoWriter.error);
}
}]; // end videoWriter finishWriting Block
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
NSLog (@"Done");
break;
}
}
}
}
(5) আপনার ইউআইআইএমেজগুলি একটি সিভিপিক্সেলবফারআরেফে রূপান্তর করুন
এই পদ্ধতিটি আপনাকে একটি সিভি পিক্সেল বাফার রেফারেন্স দেবে যা অ্যাসেট রাইটার দ্বারা প্রয়োজনীয়। এটি একটি সিজিআইমেজআরফ থেকে পাওয়া যায় যা আপনি আপনার ইউআইআইমেজ (উপরে) থেকে পান।
- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
{
// This again was just our utility class for the height & width of the
// incoming video (640 height x 480 width)
ATHSingleton *singleton = [ATHSingleton singletons];
int height = singleton.screenHeight;
int width = singleton.screenWidth;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, width,
height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
&pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, width,
height, 8, 4*width, rgbColorSpace,
kCGImageAlphaNoneSkipFirst);
NSParameterAssert(context);
CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
()) আপনার
ভিডিওটিকে ক্যামেরা রোলে নিয়ে যান কারণ AVAssetWriter সরাসরি ক্যামেরা রোলটিতে লিখতে পারে না, এটি ভিডিওটিকে "tmp / temp.mov" (অথবা আপনি যে নামের ফাইল নামটি উপরে দিয়েছিলেন) থেকে ক্যামেরা রোলে নিয়ে যান।
- (void) saveToCameraRoll:(NSURL *)srcURL
{
NSLog(@"srcURL: %@", srcURL);
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
ALAssetsLibraryWriteVideoCompletionBlock videoWriteCompletionBlock =
^(NSURL *newURL, NSError *error) {
if (error) {
NSLog( @"Error writing image with metadata to Photo Library: %@", error );
} else {
NSLog( @"Wrote image with metadata to Photo Library %@", newURL.absoluteString);
}
};
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:srcURL])
{
[library writeVideoAtPathToSavedPhotosAlbum:srcURL
completionBlock:videoWriteCompletionBlock];
}
}
উপরের জলের উত্তরটি আপনি কী করছেন তার একটি সুন্দর রূপরেখা দেয়। আমরা এই কোডটি ব্যাপকভাবে মন্তব্য করেছি যাতে আপনি দেখতে পাচ্ছেন কীভাবে এটি কার্য কোড ব্যবহার করে করা হয়েছিল।