KTVVideoProcess
A High-Performance video effects processing framework.
Install / Use
/learn @ChangbaDevs/KTVVideoProcessREADME
KTVVideoProcess
KTVVideoProcess is a High-Performance video effects processing framework. It's base on OpenGL ES, support asynchronous and multithread processing.
Flow Chart

Installation
Installation with CocoaPods
To integrate KTVVideoProcess into your Xcode project using CocoaPods, specify it in your Podfile:
pod 'KTVVideoProcess', '~> 1.2.0'
Run pod install
Installation with Carthage
To integrate KTVVideoProcess into your Xcode project using Carthage, specify it in your Cartfile:
github "ChangbaDevs/KTVVideoProcess" ~> 1.2.0
Run carthage update to build the framework and drag the built KTVVideoProcess.framework into your Xcode project.
Usage
- The Complete process needs three nodes: Source/Pipeline/Output.
Source
- The responsibility of the source is the input data, like camera or media file.
- You can create a camera source like following:
self.captureSession = [[KTVVPCaptureSession alloc] init];
self.captureSession.pipeline = self.pipeline;
if (needAudio) {
self.captureSession.audioEnable = YES;
self.captureSession.audioOutput = frameWriter;
}
[self.captureSession start];
Pipeline
- The pipeline is the real processor. It contains multiple filters inside.
- There are serial and concurrent two pipelines. The serial pipeline run on a separate thread, and it's only can process one task at the same time. The concurrent contains multiple serial pipeline, this means that it's can process multiple tasks at the same time. But when using concurrent pipeline, the timestamp of the output frame may not be continuous.
- You can create a serial pipeline like following:
NSArray <Class> * filterClasses = @[[KTVVPRGBFilter class],
[KTVVPExposureFilter class],
[KTVVPBrightnessFilter class],
[KTVVPBlackAndWhiteFilter class],
[KTVVPTransformFilter class]];
self.pipeline = [[KTVVPSerialPipeline alloc] initWithContext:self.context filterClasses:filterClasses];
__weak typeof(self) weakSelf = self;
[self.pipeline setFilterConfigurationCallback:^(__kindof KTVVPFilter * filter, NSInteger index) {
__strong typeof(weakSelf) self = weakSelf;
if ([filter isKindOfClass:[KTVVPRGBFilter class]]) {
self.RGBFilter = filter;
self.RGBFilter.enable = NO;
self.RGBFilter.red = 0.8;
} else if ([filter isKindOfClass:[KTVVPExposureFilter class]]) {
self.exposureFilter = filter;
self.exposureFilter.enable = NO;
self.exposureFilter.exposure = 0.5;
} else if ([filter isKindOfClass:[KTVVPBrightnessFilter class]]) {
self.brightnessFilter = filter;
self.brightnessFilter.enable = NO;
self.brightnessFilter.brightness = 0.2;
} else if ([filter isKindOfClass:[KTVVPBlackAndWhiteFilter class]]) {
self.blackAndWhiteFilter = filter;
self.blackAndWhiteFilter.enable = NO;
}
}];
[self.pipeline setupIfNeeded];
Output
- It's used to receive the results of pipeline.
- You can create a preview view or file writer like following:
// Preview View
self.frameView = [[KTVVPFrameView alloc] initWithContext:self.context];
self.frameView.frame = self.view.bounds;
[self.view addSubview:self.frameView];
[self.pipeline addOutput:self.frameView];
// File Writer
NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"KTVVideoProcess-temp.mov"];
self.frameWriter = [[KTVVPFrameWriter alloc] init];
self.frameWriter.outputFileURL = [NSURL fileURLWithPath:filePath];
self.frameWriter.videoOutputSize = KTVVPSizeMake(720, 1280);
self.frameWriter.videoEncodeDelayInterval = 0.0f;
if (needAudio) {
self.frameWriter.audioEnable = YES;
}
[self.frameWriter setStartCallback:^(BOOL success) {
NSLog(@"Record Started...");
}];
[self.frameWriter setFinishedCallback:^(BOOL success) {
NSLog(@"Record Finished...");
}];
[self.frameWriter setCancelCallback:^(BOOL success) {
NSLog(@"Record Canceled...");
}];
[self.frameWriter start];
if (needAudio) {
self.captureSession.audioOutput = self.frameWriter;
}
[self.pipeline addOutput:self.frameWriter];
Export
- It's used to process existing video.
- You can create a export session like following:
KTVVPExportSession * exportSession = [[KTVVPExportSession alloc] init];
exportSession.sourceURL = inputURL;
exportSession.destinationURL = outputURL;
exportSession.pipeline = pipeline;
[exportSession setCompletionCallback:^(NSURL * destinationURL, NSError * error) {
NSLog(@"KTVVPExportSession Finished");
}];
[exportSession start];
Background Mode
- You need to do something to avoid process runs in the background:
// Suspend the Source/Pieple/Output
self.captureSession.paused = YES;
[self.pipeline glFinish];
[self.frameWriter cancel];
// Wait until all operations are finished.
[self.pipeline waitUntilFinished];
[self.frameView waitUntilFinished];
[self.frameWriter waitUntilFinished];
Transform
- If the video frame contains transformation(Rotation/Flip/...). But the output can't handle transform. You can add a KTVVPTransformFilter at the end of the Pipeline. It will handle transform if needed.
License
KTVVideoProcess is released under the MIT license.
Author
- GitHub : Single
- Email : libobjc@gmail.com
Developed by Single
- SGPlayer - A powerful media player framework for iOS, macOS, and tvOS.
- KTVHTTPCache - A powerful HTTP caching framework.
Related Skills
qqbot-channel
347.2kQQ 频道管理技能。查询频道列表、子频道、成员、发帖、公告、日程等操作。使用 qqbot_channel_api 工具代理 QQ 开放平台 HTTP 接口,自动处理 Token 鉴权。当用户需要查看频道、管理子频道、查询成员、发布帖子/公告/日程时使用。
docs-writer
100.1k`docs-writer` skill instructions As an expert technical writer and editor for the Gemini CLI project, you produce accurate, clear, and consistent documentation. When asked to write, edit, or revie
model-usage
347.2kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
Design
Campus Second-Hand Trading Platform \- General Design Document (v5.0 \- React Architecture \- Complete Final Version)1\. System Overall Design 1.1. Project Overview This project aims t
