Created
May 25, 2023 01:33
-
-
Save SKaplanOfficial/0014c8d02f50574f2a035bbaf5f6f0ba to your computer and use it in GitHub Desktop.
JXA script to extract the first frame of a video and save it into a TIFF file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(() => { | |
ObjC.import("objc"); | |
ObjC.import("CoreMedia"); | |
ObjC.import("Foundation"); | |
ObjC.import("AVFoundation"); | |
ObjC.import("CoreGraphics"); | |
ObjC.import("CoreImage"); | |
ObjC.import("AppKit"); | |
const outputPath = "/Users/example/Downloads/example.tiff" | |
// Load the video file | |
const assetURL = $.NSURL.fileURLWithPath( | |
"/Users/example/Downloads/example.mov" | |
); | |
const asset = $.objc_getClass("AVAsset").assetWithURL(assetURL); | |
// Ensure the video has a video track | |
if (asset.tracksWithMediaType($.AVMediaTypeVideo).count == 0) { | |
return ""; | |
} | |
const frameCount = 15; // The number of frames to analyze | |
// Set up the AVAssetReader for reading the video frames into pixel buffers | |
const reader = $.objc_getClass("AVAssetReader").alloc.initWithAssetError( | |
asset, | |
null | |
); | |
const track = asset.tracksWithMediaType($.AVMediaTypeVideo).objectAtIndex(0); | |
const settings = $.NSDictionary.dictionaryWithObjectForKey( | |
"420v", | |
"PixelFormatType" | |
); | |
readerOutput = $.objc_getClass( | |
"AVAssetReaderTrackOutput" | |
).alloc.initWithTrackOutputSettings(track, settings); | |
reader.addOutput(readerOutput); | |
reader.startReading; | |
// Read the video frames into pixel buffers | |
let buf = readerOutput.copyNextSampleBuffer; | |
if (reader.status != $.AVAssetReaderStatusFailed) { | |
const imageBufferRef = ObjC.castRefToObject( | |
$.CMSampleBufferGetImageBuffer(buf) | |
); | |
const CIImage = $.CIImage.imageWithCVPixelBuffer(imageBufferRef) | |
const imageRep = $.NSBitmapImageRep.alloc.initWithCIImage(CIImage) | |
const imageData = imageRep.TIFFRepresentation | |
imageData.writeToFileAtomically(outputPath, true) | |
} | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment