用 Media Player 查看 AVI 文件的属性时,看到“内容”页中有“标题”、“艺术家”、“版权”、“分级”等栏目,如何能通过编程的方式修改一个 AVI 文件的这些内容?要用到哪些函数?有没有可以参考的相关资料?望大家不吝赐教,谢谢!
解决方案 »
- 关于sip2协议
- 怎样实现类似Excel复制单元格时的动态线框?
- 一个关于IOCP的问题,请高手来帮忙。
- 关于ado调用存储过程中的append方法总是失败!
- “计算机组成与结构”很重要,网上有好的资源与站点吗?看不懂书,痛苦中!盼帮助!
- Grid怎么能编辑其中的内容
- GetDeviceCaps(pd.hDC, VERTRES);返回的6744值,代表什么?
- typedef DWORD (WINAPI *MYFUNC)(DWORD,DWORD);是定义函数指针吗?为什么这样定义呢?
- 结构体数组如何解决更节省资源?
- 关于报考mcsd,答者有分
- 请问小I MSN机器人的聊天室是怎么实现的?
- 如何获得桌面的高度和宽度?或者size
但要,做成适应于各种AVI文件的通用模块就不那么简单了。因为AVI文件的格式不是一成不变的;有时会缺少或增加某些可有可无的CHUNK.得优点耐心。
最后,说一句,不要依靠MS的AVI函数,他的函数屏蔽了很多宝贵的细节,程序出错都不知道哪的错。
现在我需要修改(或增加)标题、作者、简介信息到一个 AVI 文件中,这个 AVI 文件是由一个 MPEG4 视频流和一个 MP2 音频流组成的,针对这种格式,我该怎么改呢?
This section describes the functions, structures, and macros for applications using the AVIFile services. These elements are grouped as follows:AVIFile Library Operations
AVIFileInit
AVIFileExitOpening and Closing AVI Files
AVIFileOpen
AVIFileAddRef
AVIFileRelease
GetOpenFileNamePreviewReading from a File
AVIFileInfo
AVIFILEINFO
AVIFileReadDataWriting to a File
AVIFileWriteDataUsing the Clipboard
AVIPutFileOnClipboard
AVIGetFromClipboard
AVIClearClipboardOpening and Closing Streams
AVIFileGetStream
AVIStreamOpenFromFile
AVIStreamAddRef
AVIStreamReleaseReading Stream Information
AVISTREAMINFO
AVIStreamReadData
AVIStreamDataSize
AVIStreamReadFormat
AVIStreamFormatSize
AVIStreamRead
AVIStreamSampleSize
AVIStreamBeginStreaming
AVIStreamEndStreamingDecompressing Video Data in a Stream
AVIStreamGetFrameOpen
AVIStreamGetFrame
AVIStreamGetFrameCloseCreating a File from Existing Streams
AVISave
AVISaveV
AVISaveOptions
GetSaveFileNamePreview
AVIMakeFileFromStreamsWriting Individual Streams
AVIFileCreateStream
AVIStreamSetFormat
AVIStreamWrite
AVIFileWriteData
AVIStreamWriteData
AVIStreamReleaseFinding the Starting Position in a Stream
AVIStreamStart
AVIStreamStartTime
AVIStreamLength
AVIStreamLengthTime
AVIStreamFindSample
AVIStreamEnd
AVIStreamEndTimeFinding Sample and Key Frames
AVIStreamFindSample
AVIStreamIsKeyFrame
AVIStreamNearestKeyFrame
AVIStreamNearestKeyFrameTime
AVIStreamNearestSample
AVIStreamNearestSampleTime
AVIStreamNextKeyFrame
AVIStreamNextKeyFrameTime
AVIStreamNextSample
AVIStreamNextSampleTime
AVIStreamPrevKeyFrame
AVIStreamPrevKeyFrameTime
AVIStreamPrevSample
AVIStreamPrevSampleTime
AVIStreamSampleToSampleSwitching Between Samples and Time
AVIStreamSampleToTime
AVIStreamTimeToSampleCreating Temporary Streams
AVIStreamCreate
AVIMakeCompressedStream
AVIStreamReleaseEditing AVI Streams
CreateEditableStream
EditStreamCut
EditStreamCopy
EditStreamPaste
EditStreamClone
EditStreamSetInfo
EditStreamSetName
EditStreamSetInfo 函数像是修改 AVI 文件信息的,它在 MSDN 中的描述如下:SDTAPI EditStreamSetInfo(
PAVISTREAM pavi,
AVISTREAMINFO * lpInfo,
LONG cbInfo
);AVISTREAMINFO 结构的定义为:typedef struct {
DWORD fccType;
DWORD fccHandler;
DWORD dwFlags;
DWORD dwCaps;
WORD wPriority;
WORD wLanguage;
DWORD dwScale;
DWORD dwRate;
DWORD dwStart;
DWORD dwLength;
DWORD dwInitialFrames;
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
RECT rcFrame;
DWORD dwEditCount;
DWORD dwFormatChangeCount;
char szName[64];
} AVISTREAMINFO; 不知道这个结构体中的 szName[64] 是不是就是我要修改的地方?
AVIFileInfo
AVIFILEINFO
AVIFILEINFO也不是 :(
#include "getframe.h"
#include "getframeapi.h"
#include <vfw.h>BOOL ExtractAVIFrames(CString szFileName)
{
AVIFileInit(); PAVIFILE avi;
int res=AVIFileOpen(&avi, szFileName, OF_READ, NULL); if (res!=AVIERR_OK)
{
//an error occures
if (avi!=NULL)
AVIFileRelease(avi);
return FALSE;
} AVIFILEINFO avi_info;
AVIFileInfo(avi, &avi_info, sizeof(AVIFILEINFO)); CString szFileInfo;
szFileInfo.Format("Dimention: %dx%d\n"
"Length: %d frames\n"
"Max bytes per second: %d\n"
"Samples per second: %d\n"
"Streams: %d\n"
"File Type: %d", avi_info.dwWidth,
avi_info.dwHeight,
avi_info.dwLength,
avi_info.dwMaxBytesPerSec,
(DWORD) (avi_info.dwRate / avi_info.dwScale),
avi_info.dwStreams,
avi_info.szFileType); AfxMessageBox(szFileInfo, MB_ICONINFORMATION | MB_OK); PAVISTREAM pStream;
res=AVIFileGetStream(avi, &pStream, streamtypeVIDEO /*video stream*/,
0 /*first stream*/); if (res!=AVIERR_OK)
{
if (pStream!=NULL)
AVIStreamRelease(pStream); AVIFileExit();
return FALSE;
} //do some task with the stream
int iNumFrames;
int iFirstFrame; iFirstFrame=AVIStreamStart(pStream);
if (iFirstFrame==-1)
{
//Error getteing the frame inside the stream if (pStream!=NULL)
AVIStreamRelease(pStream); AVIFileExit();
return FALSE;
} iNumFrames=AVIStreamLength(pStream);
if (iNumFrames==-1)
{
//Error getteing the number of frames inside the stream
if (pStream!=NULL)
AVIStreamRelease(pStream);
AVIFileExit();
return FALSE;
} //getting bitmap from frame
BITMAPINFOHEADER bih;
ZeroMemory(&bih, sizeof(BITMAPINFOHEADER)); bih.biBitCount=24; //24 bit per pixel
bih.biClrImportant=0;
bih.biClrUsed = 0;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biSize = 40;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
//calculate total size of RGBQUAD scanlines (DWORD aligned)
bih.biSizeImage = (((bih.biWidth * 3) + 3) & 0xFFFC) * bih.biHeight ; PGETFRAME pFrame;
pFrame=AVIStreamGetFrameOpen(pStream,
NULL/*(BITMAPINFOHEADER*) AVIGETFRAMEF_BESTDISPLAYFMT*/ /*&bih*/);
//Get the first frame
int index=0;
for (int i=iFirstFrame; i<iNumFrames; i++)
{
index= i-iFirstFrame; BYTE* pDIB = (BYTE*) AVIStreamGetFrame(pFrame, index);
CreateFromPackedDIBPointer(pDIB, index);
} AVIStreamGetFrameClose(pFrame); //close the stream after finishing the task
if (pStream!=NULL)
AVIStreamRelease(pStream); AVIFileExit(); return TRUE;
}
///The only one function that I must describe more about is: CreateFromPackedDIBPointer(). This function takes a pointer returned from AVIStreamGetFrame() function and creates a bitmap from it. As you know, the AVIStreamGetFrame() returns a pointer to DIB information about the frame. We take this pointer and create a bitmap from it.BOOL CreateFromPackedDIBPointer(LPBYTE pDIB, int iFrame)
{
ASSERT(pDIB!=NULL); //Creates a full-color (no palette) DIB from a pointer to a
//full-color memory DIB //get the BitmapInfoHeader
BITMAPINFOHEADER bih;
RtlMoveMemory(&bih.biSize, pDIB, sizeof(BITMAPINFOHEADER)); //now get the bitmap bits
if (bih.biSizeImage < 1)
{
return FALSE;
} BYTE* Bits=new BYTE[bih.biSizeImage]; RtlMoveMemory(Bits, pDIB + sizeof(BITMAPINFOHEADER), bih.biSizeImage); //and BitmapInfo variable-length UDT
BYTE memBitmapInfo[40];
RtlMoveMemory(memBitmapInfo, &bih, sizeof(bih)); BITMAPFILEHEADER bfh;
bfh.bfType=19778; //BM header
bfh.bfSize=55 + bih.biSizeImage;
bfh.bfReserved1=0;
bfh.bfReserved2=0;
bfh.bfOffBits=sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER); //54
CString FileName;
FileName.Format("Frame-%05d.bmp", iFrame);
FILE* fp=fopen(FileName, "wb");
if (fp!=NULL)
{
fwrite(&bfh, sizeof(bfh), 1, fp);
fwrite(&memBitmapInfo, sizeof(memBitmapInfo), 1, fp);
fwrite(Bits, bih.biSizeImage, 1, fp);
fclose(fp);
}
else
{
TRACE0(_T("Error writing the bitmap file"));
return FALSE;
} delete [] Bits;
return TRUE;
}