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

GoogleGeek 2003-08-19 11:11:50
在已经获得了mpeg4格式视频数据和amr压缩格式的音频数据的条件下,如何创建quicktime对应的mov文件,也就是说,如何将我得到的音频和视频数据放在quicktime对应的mov文件中,形成一个mov文件,然后让quicktime能够播放?
我有quicktime的文件格式的英文资料,但是文件格式太复杂,看不懂!
另外哪位高手能给一些apple电脑的开发网站?
...全文
90 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)
JAVA多媒体开发手册,Java多媒体框架(JMF)中包含了许多用于处理多媒体的API。它是一个相当复杂的系统,完全了解这个系统可能需要花上几周的时间,但是这篇文章将主要介绍JMF的几个核心接口和类,然后通过一个简单的例子向你展示如何利用该接口进行编程。 JMF目前的最新版本是2.1,Sun通过它向Java中引入处理多媒体的能力。下面是JMF所支持的功能的一个概述: ● 可以在Java Applet和应用程序中播放各种媒体文件,例如AU、AVI、MIDI、MPEG、QuickTime和WAV等文件。 ● 可以播放从互联网上下载的媒体流。 ● 可以利用麦克风和摄像机一类的设备截取音频和视频,并保存成多媒体文件。 ● 处理多媒体文件,转换文件格式。 ● 向互联网上传音频和视频数据流。 ● 在互联网上广播音频和视频数据。 JMF的结构 为了更好地说明JMF的结构,让我们用立体声音响做一个简单的比喻。当你CD机播放CD唱片的时候,CD唱片向系统提供音乐信号。这些数据是在录音棚中用麦克风和其他类似的设备记录下来的。CD播放机将音乐信号传送到系统的音箱上。在这个例子中,麦克风就是一个音频截取设备,CD唱片是数据源,而音箱是输出设备。 JMF的结构和立体声音响系统非常相似,在后面的文章中,你会遇到下面的这些术语: ● 数据源(Data source) ● 截取设备(Capture Device,包括视频和音频截取设备) ● 播放器(Player) ● 处理器(Processor) ● 数据格式(Format) ● 管理器(Manager) 下面让我们来看一看这些术语到底代表什么意思。 1.数据源 就像CD中保存了歌曲一样,数据源中包含了媒体数据流。在JMF中,DataSource对象就是数据源,它可以是一个多媒体文件,也可以是从互联网上下载的数据流。对于DataSource对象,一旦你确定了它的位置和类型,对象中就包含了多媒体的位置信息和能够播放该多媒体的软件信息。当创建了DataSource对象后,可以将它送入Player对象中,而Player对象不需要关心DataSource中的多媒体是如何获得的,以及格式是什么。 在某些情况下,你需要将多个数据源合并成一个数据源。例如当你在制作一段录像时,你需要将音频数据源和视频数据源合并在一起。JMF支持数据源合并,在后面的例子中我们将提到这一点。 2.截取设备 截取设备指的是可以截取到音频或视频数据的硬件,如麦克风、摄像机等。截取到的数据可以被送入Player对象中进行处理。 3.播放器 在JMF中对应播放器的接口是Player。Player对象将音频/视频数据流作为输入,然后将数据流输出到音箱或屏幕上,就像CD播放机读取CD唱片中的歌曲,然后将信号送到音箱上一样。Player对象有多种状态,JMF中定义了JMF的六种状态,在正常情况下Player对象需要经历每个状态,然后才能播放多媒体。下面是对这些状态的说明。 ● Unrealized:在这种状态下,Player对象已经被实例化,但是并不知道它需要播放的多媒体的任何信息。 ● Realizing:当调用realize()方法时,Player对象的状态从Unrealized转变为Realizing。在这种状态下,Player对象正在确定它需要占用哪些资源。 ● Realized:在这种状态下Player对象已经确定了它需要哪些资源,并且也知道需要播放的多媒体的类型。 ● Prefetching:当调用prefectch()方法时,Player对象的状态从Realized变为Prefetching。在该状态下的Player对象正在为播放多媒体做一些准备工作,其中包括加载多媒体数据,获得需要独占的资源等。这个过程被称为预取(Prefetch)。 ● Prefetched:当Player对象完成了预取操作后就到达了该状态。 ● Started:当调用start()方法后,Player对象就进入了该状态并播放多媒体。 4.处理器 处理器对应的接口是Processor,它一种播放器。在JMF API中,Processor接口继承了Player接口。 Processor对象除了支持支持Player对象支持的所有功能,还可以控制对于输入的多媒体数据流进行何种处理以及通过数据源向其他的Player对象或Processor对象输出数据。 除了在播放器中提到了六种状态外,Processor 对象还包括两种新的状态,这两种状态是在Unrealized状态之后,但是在Realizing状态之前。 ● Configuring:当调用configure()方法后,Processor对象进入该状态。在该状态下

2,542

社区成员

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

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