這是我們要去的標準QuickTime組件導出設置對話框中使用:
![enter image description here](https://i.stack.imgur.com/T6OOF.png)
對話框只有在QuickTime框架提供(不要與混淆QTKit),因此有侷限性:
- 32位buil d只有
- 沒有任何iOS集成。
你需要做的第一件事是將應用程序與Quiktime框架鏈接,請確保你建立了32位英特爾架構和構建有源體系僅設置打開。
的目標是打開對話框,設置必要的出口設置,並使用它們來導出電影。
我會提供的代碼片段以相反的順序從實際的對話框調用回到所需結構的使用開始。我們必須使用很多代碼,所以有些耐心是必要的。
對話需要一個QuickTime組件。在我們的例子中,我們將使用MPEG4組件。我們所提供的組件時,先前保存設置並打開對話框:
#import <QuickTime/QuickTimeComponents.h>
- (void)editExportSetting:(JSMovieExportSetting*)setting
{
MovieExportComponent exporter = OpenComponent(_MPEG4Component.component);
Boolean canceled;
[self updateMovieExportComponent:exporter withExportSetting:setting];
ComponentResult err = MovieExportDoUserDialog(exporter, NULL, NULL, 0, 0, &canceled);
if (!canceled)
{
if (err == 0)
{
[self updateExportSetting:setting withMovieExportComponent:exporter];
}
}
CloseComponent(exporter);
}
當用戶修改完畢以後,並且點擊確定按鈕,我們存儲供以後使用的設置。 OpenComponent
功能需要Component
數據類型。我爲它構建了一個便利的類包裝器,請參閱下面的列表。
現在,我們需要得到MPEG4組件:
- (JSQTComponent*)MPEG4Component
{
/*
MPEG-4
*/
ComponentDescription description;
description.componentType = 1936746868;
description.componentSubType = 1836082996;
description.componentManufacturer = 1634758764;
description.componentFlags = 269058096;
description.componentFlagsMask = 66207;
return [self componentWithDescription:description];
}
- (JSQTComponent*)componentWithDescription:(ComponentDescription)description
{
JSQTComponent* result = nil;
for (JSQTComponent* component in [self components])
{
if ([component isEqualToComponentDescription:description])
{
result = component;
break;
}
}
return result;
}
- (NSArray*)components
{
if (_components == nil)
{
_components = [NSMutableArray new];
QTAtomContainer resources = NULL;
OSErr err = GetComponentPublicResourceList(kQTPresetsListResourceType, 1, 0, &_componentDescription, nil, nil, &resources);
if (err != noErr)
{
NSLog(@"JSQTComponentDataModel error: %d", err);
}
else if (resources != NULL)
{
QTAtom currChild = 0;
QTAtom nextChild = 0;
OSErr err;
unsigned atomsCount = QTCountChildrenOfType(resources, kParentAtomIsContainer, 0);
for (UInt16 i=0; i < atomsCount; i++)
{
QTAtom compAtomId = 0;
if (QTFindChildByIndex(resources, kParentAtomIsContainer, kQTMetaDataCommonKeyComposer, i+1, &compAtomId))
{
Component component = (Component)compAtomId;
err = QTNextChildAnyType(resources, kParentAtomIsContainer, currChild, &nextChild);
if (err == noErr && nextChild)
{
[_components addObject:[[[JSQTComponent alloc] initWithComponent:component] autorelease]];
}
else
{
NSLog(@"Error %d getting item %d\n", err, i);
}
currChild = nextChild;
}
}
QTDisposeAtomContainer(resources);
}
}
return _components;
}
基本上我們期待與我們需要在列表中描述的組件。這個列表是爲了獲得某種類型的組件而構建的,因爲Quicktime有很多不同的東西。
我們感興趣的只是一次爲電影出口創造的。
ComponentDescription _componentDescription;
_componentDescription.componentType = MovieExportType;
_componentDescription.componentSubType = kAnyComponentSubType;
_componentDescription.componentManufacturer = kAnyComponentManufacturer;
_componentDescription.componentFlags = canMovieExportFiles;
_componentDescription.componentFlagsMask = canMovieExportFiles;
名單緩存進一步使用,不要忘了釋放它在你的dealloc。
到目前爲止,我們還算不錯。我們已經得到了我們的MPEG4組件對象,從中得到了Component
的結構。現在我們需要將我們上次存儲的設置應用到組件。
- (void)updateMovieExportComponent:(MovieExportComponent)component withExportSetting:(JSMovieExportSetting*)movieExportSetting
{
NSData* presetSettings = movieExportSetting.exportSettings;
Handle settings = NewHandleClear([presetSettings length]);
if (settings)
{
memcpy(*settings, [presetSettings bytes], GetHandleSize(settings));
// Set movie export settings from the settings QTAtomContainer
MovieExportSetSettingsFromAtomContainer(component, (QTAtomContainer)settings);
DisposeHandle(settings);
}
}
如果您在沒有任何設置的情況下第一次使用該組件,對話框將顯示一次默認值。
用戶後完成與編輯和按下OK,我們需要保存設置:
- (void)updateExportSetting:(JSMovieExportSetting*)movieExportSetting withMovieExportComponent:(MovieExportComponent)component
{
QTAtomContainer settings;
ComponentResult err = MovieExportGetSettingsAsAtomContainer(component, &settings);
if (err == 0)
{
NSData* exportSettings = [NSData dataWithBytes:*settings length:GetHandleSize(settings)];
movieExportSetting.exportSettings = exportSettings;
}
}
JSMovieExportSetting
是一個包裝,請參閱下面的清單。您可以輕鬆將其序列化爲文件以存儲設置。
最後一步是使用我們剛剛獲得的電影轉換設置。 好的新功能是我們不必再使用Quicktime,我們可以使用QTKit方法。
QTMovie* movie = [QTMovie movieWithFile:sourceFilePath error:outError];
NSDictionary* settings = [movieExportSetting movieAttributes];
[movie writeToFile:outputFilePath withAttributes:settings error:outError]
集電影的委託,實施movie: shouldContinueOperation: withPhase: atPercent: withAttributes:
,看是否需要進步。
您可以在下面找到所用類別的清單。我希望這有幫助。
JSQTComponent
@interface JSQTComponent : NSObject
{
Component _component;
ComponentDescription _componentDescription;
NSString* _name;
NSString* _info;
NSString* _icon;
}
- (id)initWithComponent:(Component)component;
@property (nonatomic, readonly) Component component;
@property (nonatomic, readonly) ComponentDescription componentDescription;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* info;
@property (nonatomic, retain) NSString* icon;
- (BOOL)isEqualToComponentDescription:(ComponentDescription)anotherComponentDescription;
@end
@implementation JSQTComponent
@synthesize成分= _component; @synthesize componentDescription = _componentDescription; @synthesize name = _name; @synthesize info = _info; @synthesize icon = _icon;
(ID)initWithComponent:(組分)組分 { 自我= [超級INIT]; (self!= nil) {component = component; [self getDescription]; } return self; }
(無效)的dealloc { [_name釋放]; [_info release]; [_icon release]; [super dealloc]; }
(無效)getDescription { OSErr ERR; 處理aName = NewHandleClear(255); 處理anInfo = NewHandleClear(255); 處理anIcon = NewHandleClear(255); Handle iconSuite = NULL;
err = GetComponentInfo(_component,& _componentDescription,aName,anInfo,anIcon); if(err == 0) {self_name = [NSString stringWithPStringHandle:aName]; self.info = [NSString stringWithPStringHandle:anInfo]; 自我。icon = [NSString stringWithPStringHandle:anIcon];
// err = GetComponentIconSuite(aComponent,& iconSuite); } DisposeHandle(aName); DisposeHandle(anInfo); DisposeHandle(anIcon); DisposeHandle(iconSuite); }
(BOOL)isEqualToComponentDescription:(ComponentDescription)anotherComponentDescription { 回報(_componentDescription.componentType == anotherComponentDescription.componentType)& & (_componentDescription.componentSubType == anotherComponentDescription.componentSubType)& & (_componentDescription.componentManufacturer == anotherComponentDescription.componentManufacturer); }
@end
JSMovieExportSetting
@interface JSMovieExportSetting : NSObject <NSCoding>
{
NSString* _name;
NSNumber* _componentSubType;
NSNumber* _componentManufacturer;
NSData* _exportSettings;
NSDictionary* _movieAttributes;
}
- (id)initWithName:(NSString*)name attributes:(NSDictionary*)attributes;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* componentSubType;
@property (nonatomic, retain) NSNumber* componentManufacturer;
@property (nonatomic, retain) NSData* exportSettings;
@property (nonatomic, readonly) NSDictionary* movieAttributes;
@end
@implementation JSMovieExportSetting
...
- (NSDictionary*)movieAttributes
{
if (_movieAttributes == nil)
_movieAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], QTMovieExport,
_componentSubType, QTMovieExportType,
_componentManufacturer, QTMovieExportManufacturer,
_exportSettings, QTMovieExportSettings, nil] retain];
return _movieAttributes;
}
- (void)setExportSettings:(NSData*)exportSettings
{
if (_exportSettings != exportSettings)
{
[_exportSettings release];
_exportSettings = [exportSettings retain];
[_movieAttributes release];
_movieAttributes = nil;
}
}
...
@end
您仍然有興趣或爲時已晚來回答這個問題? – Davyd 2012-04-17 00:51:01