目标:从内存加载电影数据,然后在mac上写入电影文件。
要做到这一点,我发现了这个: https://developer.apple.com/legacy/library/technotes/tn1195/_index.html
我的部分代码是:
void createMovieFromMemory(void *data,
Size dataSize,
Str255 fileName)
{
Handle myDataRef = NULL;
MovieImportComponent miComponent;
Track targetTrack = nil;
TimeValue addedDuration = 0;
long outFlags = 0;
OSErr err;
ComponentResult result;
Movie movie = NULL;
miComponent = OpenDefaultComponent(MovieImportType,kQTFileTypeMP4); //kQTFileTypeWave
//implementation of this is learned from the link given above
myDataRef = createPointerDataRefWithExtensions(data, /* pointer to data */
dataSize, /* size of data */
fileName, /* file name */
0, /* file type */
nil); /* mime type */
if (myDataRef)
{
OSErr err = noErr;
short id = 0;
err = MovieImportDataRef(miComponent,
myDataRef,
HandleDataHandlerSubType,
movie,
nil,
&targetTrack,
nil,
&addedDuration,
movieImportCreateTrack,
&outFlags);
if (err == noErr)
DisposeMovie(movie);
DisposeHandle(myDataRef);
}
}
现在我的问题是在内存中加载电影的正确方法是什么(用于测试)以及如何在内存中安排电影数据。
目前,我使用以下代码将电影加载到内存:
unsigned int getFileSize(FILE **file){
unsigned int size;
if(fseek(*file, 0, SEEK_END) == -1){ return -1; }
size = ftell(*file);
fseek(*file, 0, SEEK_SET);
return size;
}
char *getFileBuffer(FILE **file, unsigned int fileSize){
char *buffer = malloc(fileSize + 1);
fread(buffer, fileSize, 1, *file);
return buffer;
}
unsigned int readFileToMemory(char path[], char **buffer){
unsigned int fileSize;
FILE *file = fopen(path, "rb");
if(file != NULL){
fileSize = getFileSize(&file);
*buffer = getFileBuffer(&file, fileSize);
fclose(file);
return fileSize;
}else{
*buffer = NULL;
return -1;
}
}
我厌倦了下面的代码:
int main(int argc, const char* argv[])
{
void* pData = NULL;
Size iDataSize = 0;
Str255 strFileName="/Users/x/SAMPLE_convert.mp4";
char path[] = "/Users/x/SAMPLE.AVI";
char *buffer;
int fileSize;
fileSize = readFileToMemory(path, &buffer);
iDataSize = fileSize;
createMovieFromMemory((void*)buffer,iDataSize,strFileName);
return (0);
}
函数MovieImportDataRef()返回错误代码-50。我搜索周围找不到错误代码-50。欢迎任何建议。谢谢。
JL
答案 0 :(得分:0)
您使用的是旧版旧API。要打开电影,请使用NewMovieFromProperties():
CFStringRef path = CFStringCreateWithCString(NULL, filename, kCFStringEncodingUTF8);
Boolean boolTrue = TRUE;
QTNewMoviePropertyElement newMovieProperties[] =
{
{ kQTPropertyClass_DataLocation, kQTDataLocationPropertyID_CFStringNativePath,
sizeof(CFStringRef), &path, 0 },
{ kQTPropertyClass_NewMovieProperty, kQTNewMoviePropertyID_Active,
sizeof(boolTrue), &boolTrue, 0 },
{ kQTPropertyClass_MovieInstantiation, kQTMovieInstantiationPropertyID_AsyncOK,
sizeof(boolTrue), &boolTrue, 0 },
{ kQTPropertyClass_NewMovieProperty, kQTNewMoviePropertyID_DontInteractWithUser,
sizeof(boolTrue), &boolTrue, 0 },
{ kQTPropertyClass_MovieInstantiation, kQTMovieInstantiationPropertyID_DontAskUnresolvedDataRefs,
sizeof(boolTrue), &boolTrue, 0 },
};
Movie movie = NULL;
OSStatus err = NewMovieFromProperties(sizeof(newMovieProperties) / sizeof(newMovieProperties[0]), newMovieProperties, 0, NULL, &movie);
CFRelease(path);
if (err != noErr)
fprintf(stderr, "Failed to open movie (error %d)\n", err);
这将从文件中打开电影。您还可以从URL打开电影。你说你想从内存中打开它“用于测试目的”,但这更复杂,因为电影媒体数据可能很大,而QuickTime的设计恰恰不是将它全部加载到内存中,而只是根据需要访问媒体的一部分。如果由于某种原因你确实拥有内存中的数据,最简单的方法可能是先写入文件。
顺便说一下,虽然您没有说出来,但您似乎暗示您想要将电影从一种格式转换为另一种格式(例如AVI到MP4)。 NewMovieFromProperties实际上将从QuickTime支持的任何格式导入媒体文件(包括AVI,MOV,MP4,WAV,3GP,MP3等,不一定只是电影,还包括音频文件,静止图像等)并创建QuickTime电影结构在记忆中。然后,您可以使用任何可用的QuickTime影片导出器组件导出为另一种格式。
-50是参数错误(paramErr),请参阅CarbonCore框架中的MacErrors.h。