Get prescale size of anamorphic video using QTKit - quicktime

I have a video file that is a QuickTime .mov (H.264) - if I open with QuickTime Player 10 and check with Movie Inspector I can see that the prescaled size is 1440x1080 and the display size is 1920x1080.
I open the video with QTKit and the following attributes: QTMovieOpenAsyncOKAttribute, QTMovieIsActiveAttribute, QTMovieResolveDataRefsAttribute, QTMovieDontInteractWithUserAttribute.
Both QTMovieCurrentSizeAttribute and QTMovieNaturalSizeAttribute give 1920x1080.
If I open the movie with QuickTime 7 I can use GetMovieBox() to find the size is 1920x1080 and frames can be accessed at 1440x1080. How can I get the 1440x1080 resolution information using QTKit ?
I already tried using the affine transform as given in this question: QTMovieCurrentSizeAttribute and QTMovieSizeDidChangeNotification replacements but it gave an identity transform.

You need to get the dimensions of the actual video track, not the movie.
QTTrack* videoTrack = nil;
for (QTTrack* track in [movie tracks])
{
if ([track attributeForKey:QTTrackMediaTypeAttribute] == QTMediaTypeVideo)
{
videoTrack = track;
break;
}
}
NSSize dimensions = [(NSValue*)[videoTrack attributeForKey:QTTrackDimensionsAttribute] sizeValue];
Usually there is no need to do it, because dimensions of the video track and QTMovieNaturalSizeAttribute are equal. However, with anamorphic videos movie natural size attribute tells us how the video should be displayed, when track dimensions represent size of the actual video frame (which is smaller).
QTMovieCurrentSizeAttribute is odd add deprecated, it is not related to the data at all.

Related

Can AVCaptureSession use custom resolution

I'm using AVCaptureSession to capture and record a video.
I need to record the video at a 4:3 ratio, and with a good resolution.
Is there a way to specify a custom resolution when capturing using AVCaptureSession?
I tried using the native presets but the problem is that I need to capture at a 4:3 ratio, and almost all of the presets are 16:9. and the ones that are 4:3 has very low resolution.
I can't fide any other way to change the preset to a custom one, what if I need to capture a 4:3 video with better resolution? Any ideas?
AVCaptureSession presets cover only a small subset of the capabilities of a device camera (the ones most apps want quick, easy access to). For more fine-grained control — such as to select a capture resolution not provided by a session preset — you need to use capture formats instead.
Look at the capture device's formats property, an array of AVCaptureDeviceFormat objects. Enumerate through that array until you find one whose dimensions are what you want. To get the dimensions, look at the format's underlying CMFormatDescription:
let fdesc = format.formatDescription
let dims = CMVideoFormatDescriptionGetDimensions(fdesc)
NSLog("%d x %d", dims.width, dims.height)
Once you've found the format you want, lock the device for configuration and set its activeFormat:
if try device.lockForConfiguration() {
device.activeFormat = myChosenFormat
// set up other things like activeVideoMinFrameDuration if you want
device.unlockForConfiguration()
}
You can find out more about configuring a capture session via AVCaptureDeviceFormat in Apple's programming guide and the WWDC2013 session that introduced device formats back in iOS 7.0. (Most of what you'll find about this topic is aimed at slow-motion video, taking high-res stills during video, and other things that you can't do with session presets, but those aren't the only things you can do with capture formats.)
Just record at the given aspect ratio and use an AVMutableComposition to crop the output video to the required aspect ratio: If you adjust the preview layer to mask to 4:3 this will appear seamless to the user.

Unable to render video with size greater than 640x640

I am using AVAssetExportSession to export a video saved in my documents directory. I wish to apply a CALayer to the video and hence am using AVMutableVideoComposition and setting necessary AVMutableVideoCompositionInstruction and video exports fine.
My issue is, say the original video is of resolution 1920x1080 now when I export this video by setting the rendersize of the video composition to 1920x640 it gives me a video of size 640x360.
I tried setting the rendersize to smaller values like 300x300 where I get the resultant exported video of size 300x300 of course by cropping extra contents. I then tried setting the rendersixe to 700x700 it resulted into a 640x640 video.
What I could understand is that it maintains the aspect ratio as per the render size we set, hence when i set the size to 1920x1080 it gives a 630x360 video maintaining the ratin of 16:9. Similarly when i set the size to be 700x700 it results in a video of size 640x640 with aspect ratio 1:1.
The Problem
I want the video size to be the same as its original size. But when I set the size of the mutablevideoComposition to the naturalSize of the original videotrack it limits me to a size below 640x640(if the size is beyond 640x640).
Is this a known behaviour? or am I missing something. If it is a known behaviour is there another way wherein I can export the video at its original size or size greater than 640x640.
Help will be deeply appreicated. Thanks in anticipation.
I figured it. It was a simple mistake. I was initializing the export session with AVAssetExportPreset640x480 instead of AVAssetExportPreset1920x1080.
When you set the preset the AVExportSession maintains the aspect ratio of your video which is bigger then the preset in your case that is how you were getting a 640x360 when your video was 1920x1080 thereby maintaining the aspect ratio.

Compress video like iOS's camera roll

Background:
I am recording a video and then uploading it.
Problem:
I compressed the video using this solution (medium quality) but it doesn't:
keep the original dimensions of the video
have as good a compression ratio as camera roll's.
I need similar compression (size and dimensions) like camera roll.
If it's not possible, do we have a workaround, say, automatically select the file from the iOS video picker (for upload)?
You can use AVAssetWriter and set custom compression settings. You can even compress the video while you're recording so you don't have to re-process the video before upload. Search around, there's tons of examples.

Exporting AVCaptureSession video in a size that matches the preview layer

I'm recording video using AVCaptureSession with the session preset AVCaptureSessionPreset640x480. I'm using an AVCaptureVideoPreviewLayer in a non-standard size (300 x 300) with the gravity set to aspect fill while recording. It's setup like this:
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.frame = _previewView.bounds; // 300 x 300
[_previewView.layer addSublayer:_previewLayer];
After recording the video, I want to write it to a file in quicktime format. During playback, I'm once again playing the video in a 300 x 300 non-standard size layer. Because these videos will ultimately be transferred over a network connection, it seems wasteful to keep the full 640x480 video.
What's the best way to export a video to match my 300 x 300 preview layer? I'm an AVFoundation noob, so if I'm going about this the wrong way please let me know. I just want the recorded video displayed in the preview layer during recording to match the video that is exported on disk.
Video Resolution and Video Size are two different things. Resolution stands for clarity, higher resolution means higher clarity. Whereas, Video size is the bounds in which to display the video. Depending on the video resolution and aspect ratio of the video, the video will stretch or shrink, when seen in the viewer.
Now as the facts have been explained, You can find Your answer here:
How do I use AVFoundation to crop a video
Perform the steps in this order:
Record Video to disk.
Save from Disk to asset library.
Delete from disk.
Perform the steps mentioned in the above link.
NOTE: Perform the steps after recording and writing your video to asset library, saveComposition being the saved asset.
and provide your size in this step:videoComposition.renderSize = CGSizeMake(320, 240); as videoComposition.renderSize = CGSizeMake(300, 300);
And an advice. Since writing the file to disk, then to library, then again back to disk is kind of a lengthy operation. Try doing it all asynchronously using a dispatch_queue or operationBlock
Cheers, Have Fun.

How to get the coordinates from the actual video playing inside the MPMoviePlayerController?

I have a MPMoviePlayerController playing a video.
My problem is that, video's dimensions change to maintain the aspect ratio and hence many time there is a big black gap between the video's boundaries and that of the Player.
The black gap is horizontal and vertical.
Is there a way I can get to know what is the rectangle the actual video is contained in?
Then I could find out the touch coordinates with respect to that of the video.
To get the proper dimensions / aspect ratio of the movie content, you can use the MPMoviePlayerController property naturalSize.
From the MPMoviePlayerController Class Reference
naturalSize
The width and height of the movie frame. (read-only)
#property (nonatomic, readonly) CGSize naturalSize
Discussion
This property reports the clean aperture of the video in
square pixels. Thus, the reported dimensions take into account
anamorphic content and aperture modes.
It is possible for the natural size of a movie to change during
playback. This typically happens when the bit-rate of streaming
content changes or when playback toggles between audio-only and a
combination of audio and video.
Availability
Available in iOS 3.2 and later.
Declared In
MPMoviePlayerController.h
Now lets assume you are playing a movie that returns 280x150 for its natural size. That results into an aspect ration of roughly 1.87 (width divided by height). Now let us assume you have a screen resolution of 768x1024 (iPad, portrait). If now you wanted to display that movie in the most screen filling way but still keep some of your controls visible, you would use the following calculation for the actual MPMoviePlayerController.view height:
768 / 1.87 = 411 (rounded)
The resulting frame is:
MPMoviePlayerController.view.frame = CGRectMake(0.0f,
(1024.0f - 411.0f) / 2.0f,
768.0f,
411.0f);

Resources