很急?1000分,如何用编程的方式创建quicktime文件?

GoogleGeek 2003-08-19 11:11:50
在已经获得了mpeg4格式视频数据和amr压缩格式的音频数据的条件下,如何创建quicktime对应的mov文件,也就是说,如何将我得到的音频和视频数据放在quicktime对应的mov文件中,形成一个mov文件,然后让quicktime能够播放?
我有quicktime的文件格式的英文资料,但是文件格式太复杂,看不懂!
另外哪位高手能给一些apple电脑的开发网站?
...全文
85 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
GoogleGeek 2003-10-30
  • 打赏
  • 举报
回复
问题已经圆满解决
quicktime的文件格式很new B
GoogleGeek 2003-09-20
  • 打赏
  • 举报
回复
mpeg4标准太复杂了,并不是很容易看懂的,我相信现在国内能够完全掌握的人还很少
GoogleGeek 2003-09-20
  • 打赏
  • 举报
回复
难道没有人熟悉apple计算机?:

itanynj@msn.com
jerry_hsu 2003-09-20
  • 打赏
  • 举报
回复
其实你只要按照mpeg4的标准做应该就可以了吧。
GoogleGeek 2003-09-03
  • 打赏
  • 举报
回复
to 楼上
不能使用工具
我必须用编程的方式进行,因为我的数据是动态采集的
hbffff 2003-09-03
  • 打赏
  • 举报
回复
找苹果的工具,不就是将视频流和音频流加入文件吗,我想有这样的工具。
有时间我倒是想写代码解决。
GoogleGeek 2003-09-02
  • 打赏
  • 举报
回复
各位兄弟,救救我啊
GoogleGeek 2003-09-01
  • 打赏
  • 举报
回复
faint!!
在quicktime的文件格式中没有说明怎么描述mpeg4格式的video sample
我现在不知道怎么扩充video decrible!
常规的Video Sample Description的大小是86 bytes,而mpeg4格式的video增加了69bytes来描述esds atom,要命的我怎么知道esds atom的定义和用法阿!!!!
how to describe the mpeg4's sample?
how to get the specific "esds" atom?
GoogleGeek 2003-09-01
  • 打赏
  • 举报
回复
lucky2all(lucky)
您能不能留下一个联系方式,我想和你详谈

itanynj@msn.com
psu.song@163.com
mfc_faq@msn.com
GoogleGeek 2003-09-01
  • 打赏
  • 举报
回复
您说得对,我不是在作encoder,我只是要将我采集的mpeg4格式的视频和amr格式的音频合成在一起,形成一个mov文件,然后用quicktime播放这个文件,之所以选择mov文件格式,因为现有的播放器都不支持amr音频,而quicktime却可以,当然了,选择mov,部分原因是我们后面用mp4格式

mpeg4ip的工程我看过,他们提供了mp4的api,如果做成mov文件,改动的地方很多,
我们的项目是基于sourcefore上的那个ffmpeg,我已经将mp4的api集成到ffmpeg了,但是没有用!因为mp4比mov更复杂!
我们最终的运行平台是手机,用不到directdraw!
GoogleGeek 2003-09-01
  • 打赏
  • 举报
回复
a frame ,a sequence of audio data called a sample in streaming media?
----------------------------
yes!
quicktime stores media data in samples,a sample is a single element in a sequence of time-ordered data,but samples are stored in a series of chunks in a media.Chunks are a collection of data sample in a media that allowed optimized data access!
lucky2all 2003-09-01
  • 打赏
  • 举报
回复
sorry,我不是做这一个行的,仅仅是接触过,
a frame ,a sequence of audio data called a sample in streaming media?

lucky2all@yahoo.com
lucky2all 2003-08-31
  • 打赏
  • 举报
回复
见鬼,我昨天发的帖子怎么没了,
你可以把quicktime的结构用图形先画出来,看看是否那个地方逻辑出问题了
chunk是可以精确定位的,
GoogleGeek 2003-08-30
  • 打赏
  • 举报
回复
to lucky2all(lucky)
上面是我自己写的部分垃圾代码
我都快累死了,还是无法高定

救命啊!!!

要钱,要5000分都行!

否则我可要失业了!!
555555555555555555555555555555555555555555。。。。。。。。。。。。。。。。。

GoogleGeek 2003-08-30
  • 打赏
  • 举报
回复
// a kind of media information atom,
//store the handler's specific information for a trak's media data.
// can use this information to map from media time to media data and to process the media data
class vmhdAtom:public baseAtom
{
public:
char m_version;
char m_flags[3];
INT16 m_graphicMode;
INT16 m_opcolor[3];

//constructor
vmhdAtom(int type=_MKTAG('v','m','h','d'))
{
m_size=GetConvertedSize(sizeof(*this));
m_type=type;
m_version=0;
//used to distinguish between movies created with quicktime1.0 and the newer
m_flags[2]=1;// the newer creator
//0x40:Dither the image (if needed),otherwise do a copy.
m_graphicMode=0x4000;
for(int i=0;i<3;i++)
m_opcolor[i]=0x8;
}

UINT GetAtomSize()
{
return sizeof(*this);
}

void Mov_Write_Atom(FILE *pFile)
{
fwrite(this,sizeof(*this),1,pFile);
}

};

class DataReferenceTable:public baseAtom
{
public:
char m_version;
char m_flags[3];
char *m_pRefData;

//constructor
DataReferenceTable(int type=_MKTAG('a','l','i','s'))
{
m_size=GetConvertedSize(sizeof(*this)-4);//0xc000000-->converted
m_type=type;
m_version=0;
m_flags[2]=1;
m_pRefData=0;
}

UINT GetAtomSize()
{
return sizeof(*this)-4;
}

void Mov_Write_Atom(FILE *pFile)
{
fwrite(this,sizeof(*this),1,pFile);
}
};

struct st_sub_drefAtom
{
UINT m_size;
UINT m_type;
char m_version;
char m_flags[3];
UINT m_entries;
};
class drefAtom:public baseAtom
{
public:
char m_version;
char m_flags[3];
UINT m_entries;
DataReferenceTable *m_pDataReferenceTable;

//constructor
drefAtom(int type=_MKTAG('d','r','e','f'))
{
m_size=GetConvertedSize(sizeof(*this)-4);//0x1c000000-->converted
m_type=type;
m_version=0;
ZeroMemory(m_flags,3);
m_entries=0x1000000;
m_pDataReferenceTable=new DataReferenceTable();//just ignore this atom

}

~drefAtom()
{
if(m_pDataReferenceTable)
delete m_pDataReferenceTable;
}

UINT GetAtomSize()
{
return sizeof(*this)-4;
}

void Mov_Write_Atom(FILE *pFile)
{
st_sub_drefAtom *psub=(st_sub_drefAtom*)this;
fwrite(psub,sizeof(st_sub_drefAtom),1,pFile);
if(m_pDataReferenceTable)
m_pDataReferenceTable->Mov_Write_Atom(pFile);
}

};

//the data handler compoent uses the atom to interpret the media data, asscociated with the hdlr atom
class dinfAtom:public baseAtom
{
public:
drefAtom m_drefAtom;
//constructor
dinfAtom(int type=_MKTAG('d','i','n','f'))
{
m_size=GetConvertedSize(sizeof(*this)-4);//0x24000000-->converted
m_type=type;
}

UINT GetAtomSize()
{
return sizeof(*this)-4;
}

void Mov_Write_Atom(FILE *pFile)
{
baseAtom*psub=(baseAtom*)this;
fwrite(psub,sizeof(baseAtom),1,pFile);
m_drefAtom.Mov_Write_Atom(pFile);
}
};

class SampleDesTable:public baseAtom
{
public:
char m_reserved[6];
//contain the index of the data reference to use to retrieve data associated with
//samples that use this sample des atom
INT16 m_dataReferenceIndex;

//constructor
SampleDesTable()
{
m_size=0;//later
m_type=0;//specifiy later
ZeroMemory(m_reserved,6);
}
// should add the specific media type data here,eg.pointer holder
void Mov_Write_Atom(FILE *pFile)
{

//important

//according the m_type to write the sample data
}
};

typedef st_sub_drefAtom st_sub_stsdAtom;
//sample description atom must contain at least one entry
//beacuse it contains the data reference index field that indicates which data
//reference atom to use to retrieve the meida samples
class stsdAtom:public baseAtom
{
//varies depending on the media type
public:
char m_version;
char m_flags[3];
UINT m_entries;
SampleDesTable *m_pSampleDesTable;//stsc atom has the table index as ID

BOOL CreateSampleDesTable()//how about renewing memory?
{
if(m_entries>=1)
{
try
{
m_pSampleDesTable=new SampleDesTable[m_entries];
return TRUE;
}
catch(...)
{
return FALSE;
}
}

return FALSE;
}

//constructor
stsdAtom(int type=_MKTAG('s','t','s','d'))
{
m_size=GetConvertedSize(sizeof(*this)-4);//recalculate in later
m_type=type;
m_version=0;
ZeroMemory(m_flags,3);
m_entries=GetConvertedSize(1);// at least one entries in the atom
m_pSampleDesTable=0;
}

UINT GetAtomSize()
{
return sizeof(*this)-4;
}

void Mov_Write_Atom(FILE *pFile)
{

//should change the m_entries to the converted one
st_sub_stsdAtom *psub=(st_sub_stsdAtom*)this;
fwrite(psub,sizeof(st_sub_stsdAtom),1,pFile);
if(m_pSampleDesTable)
{
//write the table item
}

}
};

// used to index from time to sample number
struct TimeSampleTable
{
UINT m_sampleCount;
UINT m_sampleDuration;
};

typedef st_sub_drefAtom st_sub_sttsAtom;

//stts atom stores duration information for media's samples
//providing a mapping from a time in a media to the corresponding data sample
//if a video has a constant frame rate,the table will have only one entry
class sttsAtom:public baseAtom
{
public:
char m_version;
char m_flags[3];
UINT m_entries;
TimeSampleTable *m_pTimeSampleTable;

BOOL CreateTimeSampleTable()
{
//if(m_pTimeSampleTable==0)

return FALSE;
}
//constructor
sttsAtom(int type=_MKTAG('s','t','t','s'))
{
m_size=GetConvertedSize(sizeof(*this)-4);//recalculate later
m_type=type;
m_version=0;
ZeroMemory(m_flags,3);
m_entries=0;
m_pTimeSampleTable=0;
}

UINT GetAtomSize()
{
return sizeof(*this)-4;
}

void Mov_Write_Atom(FILE *pFile)
{
st_sub_sttsAtom *psub=(st_sub_sttsAtom*)this;
fwrite(psub,sizeof(st_sub_sttsAtom),1,pFile);
if(m_pTimeSampleTable)
{
//write the table item
}
}

};

typedef st_sub_drefAtom st_sub_stssAtom;

//indentify the key frames in the media,
//key frames define starting points for portions of a temporally compressed
//each entry in the table identifies a sample that is a key frame for the media,
//if no sync sample exists,then all the samples are key frames
class stssAtom:public baseAtom
{
public:
char m_version;
char m_flags[3];
UINT m_entries;
//each sample number corresponds to a key frame
UINT *m_pSampleTable;//??

//constructor
stssAtom(int type=_MKTAG('s','t','s','s'))
{
m_size=GetConvertedSize(sizeof(*this)-4);//recalculate later
m_type=type;
m_entries=0;
m_pSampleTable=0;
}

UINT GetAtomSize()
{
return sizeof(*this)-4;
}

void Mov_Write_Atom(FILE *pFile)
{
st_sub_stssAtom *psub=(st_sub_stssAtom*)this;
fwrite(psub,sizeof(st_sub_stssAtom),1,pFile);
if(m_pSampleTable)
{
//write the table item
}
}

};

//identify the chunk for each sample in a media
struct SampleChunkTable
{
UINT m_firstChunk;
UINT m_sampleCount;//samples per chunk
UINT m_sampleDesID;//??how to get this ID
};
GoogleGeek 2003-08-30
  • 打赏
  • 举报
回复
/*
this file is created by songyewen
how to create the time information ?
*/

#include "systems.h"
#include <sys/timeb.h>
#include <time.h>

#define _MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
#define _MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))

typedef unsigned short UINT16;
typedef signed short INT16;
typedef unsigned char UINT8;
typedef unsigned int UINT32;
typedef unsigned __int64 UINT64;
typedef signed char INT8;
typedef signed int INT32;
typedef signed __int64 INT64;
typedef unsigned int UINT;

UINT g_trackID=1;//cannt be zero

/*
the function of creating the time information of quicktime
*/

static int gettimeofday(struct timeval *tp, void *tz)
{
struct _timeb timebuffer;

_ftime( &timebuffer );
tp->tv_sec = timebuffer.time;
tp->tv_usec = timebuffer.millitm * 1000;
return 0;
}

// Mov start date is 1/1/1904
// 208284480 is (((1970 - 1904) * 365) + 17) * 24 * 60 * 60
UINT32 MovGetAbsTimestamp() {
struct timeval tv;
gettimeofday(&tv, NULL);// start from 1970
UINT32 ret;
ret = tv.tv_sec;
ret += 2082844800;
return ret;
}

static uint32_t to_tag(uint8_t *buf)
{
return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
}

static uint32_t to_be32(uint8_t *buf)
{
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}

//convert the size to the high-->low sequence,
//when write it to file,according quicktime file format
UINT GetConvertedSize(UINT m_size)
{
UINT tempSize=0;
char byte=0;
if(m_size>=0)
{
tempSize=char(m_size>>24);
byte=char(m_size>>16);
tempSize+=byte<<8;
byte=char(m_size>>8);
tempSize+=byte<<16;
byte=char(m_size);
tempSize+=byte<<24;
}

return tempSize;
}

/****************************************************************
================information======================
Find a video sample:
1.Determines the time in the media time corrdinate system,see mdhd Atom,find the time base and get the time
2.Examine the time-to-sample atom to get the sample number that contains the data for the specified time
3.Scan the chunk-to-sample atom to discover which chunk contains the sample
4.Extracts the offset to the chunk from the chunk offset atom
5.Finds the offset within the chunk and the sample's size by using the sample size atom

****************************************************************/

class baseAtom
{
public:
UINT m_size;
int m_type;

void Mov_Write_Atom(FILE *pFile)
{
}

UINT GetAtomSize()
{
return sizeof(*this);
}
} ;

// the 'wide' atom is exactly 8 bytes in size,and consists solely of its size and type field!
class freeAtom:public baseAtom
{
public:
char *pFreeBuffer;
freeAtom(int type=_MKTAG('f','r','e','e'))
{
m_size=GetConvertedSize(sizeof(*this)-4);
m_type=type;
pFreeBuffer=0;
}

void Mov_Write_Atom(FILE *pFile)
{
fwrite(this,8,1,pFile);
}
};
typedef freeAtom skipAtom;

//we can only understand the data in this atom by using media-data stored in the movie atom
class mdatAtom:public baseAtom
{
public:
char *pDataBuffer;

UINT operator++()
{
m_size++;//dynamically change
}

mdatAtom(int type=_MKTAG('m','d','a','t'))
{
m_type=type;
m_size=0;//not the actual atom size
}

void Mov_Write_Atom(FILE *pFile)
{
// m_size=GetConvertedSize(m_size);
// fwrite(this,8,1,pFile);
}
};

//specifies the characteristics of a media
class mdhdAtom:public baseAtom
{
public:
char m_version;
char m_flags[3];
UINT m_createTime;
UINT m_modifyTime;
UINT m_timeScale;
UINT m_duration;
INT16 m_language;
INT16 m_quality;

//constructor
mdhdAtom(int type=_MKTAG('m','d','h','d'))
{
m_size=GetConvertedSize(sizeof(*this));//32 bytes
m_type=type;
m_version=0;
ZeroMemory(m_flags,3);
m_createTime=GetConvertedSize(MovGetAbsTimestamp());
m_modifyTime=GetConvertedSize(MovGetAbsTimestamp());
m_timeScale=GetConvertedSize(600);
m_language=0;//different from mp4 definition
m_quality=0;
}

UINT GetAtomSize()
{
return sizeof(*this);
}

void Mov_Write_Atom(FILE *pFile)
{
fwrite(this,sizeof(*this),1,pFile);
}
};

//This atom identifies the media handler component that is to be used to interpret the media data.
//Note that the atom tells you the kind of media this media atom contains
//¡ªfor example, video or sound. The layout of the media information atom is
//specific to the media handler that is to interpret the media.
class hdlrAtom:public baseAtom
{
public:
char m_version;
char m_flags[3];
UINT m_componentType;//mhlr?dhlr---> used for media atom
UINT m_subType;//'vide' ?'soun'
UINT m_manufacturer;
UINT m_componentFlags;
UINT m_componentFlagsMask;
//the header size is 24 bytes
//mp4:C string,not pascal string
/*
parse:
int len=0;
while(get_byte(pFile)&&++len<(atom_size-24)));//just skip
-------------------------------------------------------------
mov:pascal string
parse:
len=get_byte(pFile);
buffer=new char[len+1];
get_buffer(pFile,buffer,len);
buffer[len]='\0';
delete[] buffer;
*/
char *m_pComponentName;

/*
UINT GetSize()
{
//m_size=sizeof(*this)-4+strlen(m_pComponentName);
m_size=sizeof(*this)-4;//
return m_size;
}
*/

BOOL SetComponentName(char *pszstrName)
{
if(pszstrName!=NULL&&m_pComponentName!=pszstrName)
{
char *charTemp=m_pComponentName;
try
{
m_pComponentName=new char[strlen(pszstrName)+1];
if(charTemp!=0)
delete[] charTemp;
strcpy(m_pComponentName,pszstrName);
return TRUE;
}
catch(...)
{
m_pComponentName=charTemp;//restore
return FALSE;
}
}

return FALSE;
}
//constructor
hdlrAtom(int type=_MKTAG('h','d','l','r'))
{
m_size=GetConvertedSize(sizeof(*this)-4);//ignore the component name
m_type=type;
m_version=0;
ZeroMemory(m_flags,3);
m_componentType=_MKTAG('m','h','l','r');
m_pComponentName=0;

m_manufacturer=0;//reserved
m_componentFlags=0;//reserved
m_componentFlagsMask=0;//reserved
}

UINT GetAtomSize()
{
return sizeof(*this)-4;
}

void Mov_Write_Atom(FILE *pFile)
{
fwrite(this,sizeof(*this)-4,1,pFile);
}

};
GoogleGeek 2003-08-29
  • 打赏
  • 举报
回复
难道整个csdn就没有一个人在apple计算机上进行开发?
真是中国开发人员的悲哀!

难道就没有一个人研究过quicktime的文件格式?

天啊!救救我啊!
那里有apple的开发论坛??
lucky2all 2003-08-29
  • 打赏
  • 举报
回复
我写过,quicktime的文件格式定义几乎成了mpeg4文件存储的标准,但自己去解析
还是有点复杂,你可以到apple下载开发库,那样就简单很多。

#include "QTML.h"
#include "Movies.h"
#include "quickdraw.h"

c2pstr (pathName); // Convert to Pascal string
FSMakeFSSpec (0, 0L, (unsigned char *)pathName, &fileSpec);

OpenMovieFile (&fileSpec, &theFile, fsRdPerm);
NewMovieFromFile (&theMovie, theFile,NULL, NULL,newMovieActive, NULL);
CloseMovieFile (theFile);
forestassure 2003-08-19
  • 打赏
  • 举报
回复
具体做什么开发?
GoogleGeek 2003-08-19
  • 打赏
  • 举报
回复
help me!!
加载更多回复(1)

2,541

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧