基于Delphi的摄像头软件控制设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

河南科技学院
200X 届本科毕业论文(设计)
论文(设计)题目:基于Delphi的摄像头软件控制设计
学生姓名:X X
所在院系:信息工程学院
所学专业:计算机科学与技术
导师姓名:XXX
完成时间:2007-05-20
摘要
本文介绍了在Delphi中如何实现视频捕捉、音频的同步录制、图像的实时捕获、视频流的回放等功能,着重分析了视频监控系统中高性能硬盘录像与适时保存的实现。

本设计主要利用微软公司的VFW软件包和AVICap窗口类的成员函数来实现视频流的捕获,并借助于Delphi自带的多媒体组件Mediaplayer来实现音频信息的同步录制;对于捕捉到的视频信息,通过帧回调函数将其送往用户视窗,完成视频流的适时显示;对于需要进行视频录像的用户来说,软件提供了长时与短时两种模式,并能实现硬盘空间的自动检测和录像的适时保存。

本软件技术切实可行,运行环境稳定可靠,对那些需要视频捕捉而对系统要求不是很高的部门和领域,本文提供了一种简单易行的办法,同时为广大视频编程爱好者提供了有益的借鉴。

关键词:VFW,AVICap窗口类,视频捕捉,捕捉窗口,视频对话框
The Software Control Design of Camera Based on Delphi
Information engineering school
computer science and technology department
zhou jing
Abstract
This paper introduces how to achieve the functions such as video capture,synchronous recroding of audio,real-time image capture,video streaminp and so on in Delphi,and focused on analysing the timely preservation of the high-performance hard disk video in the video monitoring system.In the process of designing the software,the VFW packages of Microsoft software and AVIcap window category members were taken advantage primarily to achieve the function of video streaming capture.At the same time ,it realized the Synchronized record of audio information with the aid of multimedia components of Delphi.As to captured video information,it sends windows users through frame callback function to complete the display of the timely video.As to the users need to be videotaped,the software provides a long and short time in two modes and achieved automatic detection of the hard disk space and timely preservation of the viedo.The technology of software is practical and the enviroment is stable and reliable.In addition,this article provides a simple and acceptable approach for those sectors and areas that the need of video capture system is not in very high demand.In the meantime,it supplys a useful reference to the majority enthusiasts who love video programming.
Key words : VFW, AVICap windows class, video capture, window capture, video dialog
目录
1.引言 (1)
2.开发环境与基本技术 (1)
2.1开发环境 (1)
2.2VFW简介 (2)
2.3AVICap类的功能与函数 (2)
2.3.1AVICap类的基本功能 (2)
2.3.2AVICap窗口类的主要函数与宏 (3)
2.3.3视频捕捉结构 (5)
3.软件的结构与功能 (5)
3.1软件的层次结构 (5)
3.2软件的功能 (5)
4.软件控制设计的实现 (6)
4.1视频捕获流程 (6)
4.2软件设计的实现 (7)
4.2.1主窗体设计 (7)
4.2.2启动摄像与音频录制 (10)
4.2.3帮助文件的设计 (16)
4.3设计中的问题 (17)
5.软件测试 (17)
5.1测试技术 (17)
5.2测试结果与评价 (18)
6.结束语 (18)
致谢 (19)
参考文献 (20)
1.引言
随着数字视频监控、可视电话、电视会议等多媒体技术应用的迅速兴起,越来越多的场合需要对数字视频信号进行捕捉。

目前,市场上有两种数字视频监控系统类型,一种是以数字录像设备为核心的视频监控系统,另一种是以嵌入式视频Web服务器为核心的视频监控系统。

其中,数字监控录像系统又分为两类:一类是基于PC机组合的计算机多媒体工作方式;另一类是嵌入式数字监控录像系统。

基于PC机组合的计算机多媒体工作方式具有诸多优越性,部分地取代了模拟视频监控模式,但性能不够稳定;嵌入式数字录像系统以应用为中心,在专用性等方面具有突出的特点,但它需要由嵌入式处理器、嵌入式操作系统及应用软件等共同支持,在网络功能、音视频同步等方面也难令人满意;嵌入式视频Web 服务器方式性能稳定可靠,无需专人管理,但技术过难、对硬件的要求也较高。

因此,主流监控系统虽然技术先进,但却难于推广,通常只用在专业领域。

为此,本软件借助微软的软件开发工具包(SDK)[1],简称VFW[2]对摄像头进行了软件控制设计,并通过在安装摄像头驱动程序时,系统文件里产生的AVICAP32.DLL[1]动态链接库获得视频窗口,实现对摄像头的各种操作。

设计好的软件不但简单易用,而且在录制视频文件(*.avi)的同时能够实现音频信息(*.wav)的同步录制,使得录像的制作简单易行,很好地满足了广大视频用户的需求。

2.开发环境与基本技术
2.1开发环境
Delphi是著名的Borland公司开发的可视化软件开发工具[3]。

它被称为第四代编程语言,具有简单、高效、功能强大的特点。

Delphi具有以下的特性:(1)基于窗体和面向对象的方法。

Delphi把Windows编程的回调、句柄处理等繁复过程都放在一个不可见的Romulam覆盖物下面,这样您可以不为它们所困扰,轻松从容地对可视部件进行编程。

而面向对象的程序设计Object-Oriented Programming,简记为OOP)是Delphi诞生的基础。

OOP立意于创建软件重用代码,具备更好地模拟现实世界环境的能力,这使它被公认为是自上而下编程的优胜者。

它通过给程序中加入扩展语句,把函数“封装”进Windows编程所必需的“对象”中。

如本例中的AVICAP窗口类、DIALOG对话框类等。

(2)与Windows编程紧密结合,强大而成熟的组件技术。

Delphi不仅自身组件十分丰富,而且对第三方组件也有良好的兼容性。

如图2-1所示的附加组件栏、图2-2所示的第三方皮肤组件栏。

图2-1附加组件栏
图2-2第三方皮肤组件栏
2.2VFW简介
VFW(Video for Windows)是微软公司关于数字视频的一个软件包。

它能使应用程序通过数字化设备从传统的模拟视频源得到数字化的视频剪辑,VFW的一个关键思想是播放时不需要专用硬件。

为了解决数字视频数据量大的问题,需要对数据进行压缩,而VFW引进了AVI的文件标准,该标准未规定如何对视频进行捕捉、压缩及播放,仅规定视频和音频该如何存储在硬盘上及在AVI文件中交替存储视频帧和与之相匹配的音频数据。

通过VFW,开发人员通过发送消息或设臵属性来捕捉、播放和编辑视频剪辑。

当用户在安装VFW时,安装程序会自动地安装配臵视频所需要的组件,如设备驱动程序、视频压缩程序等[9]。

VFW主要由6个模块组成。

具体如表2.1所列:
表2.1 VFW功能模块
2.3AVICap类的功能与函数
2.3.1AVICap类的基本功能
AVICap支持实时的视频流捕捉和视频单帧捕捉。

使用AVICap窗口类可创建具有一些基本功能的窗口,例如视频图像的预览、设臵捕捉参数的对话框、音频、视频捕捉的独立控制等。

AVICap中的回调函数可使应用程序向用户提供有关捕捉的状态,包括进行的过程指示,以及任何可能产生的错误。

开发人员可以设臵一个标志用来指示在什么时候采集到音频,什么时候采集到视频。

这样,应用程序可以直接使用数据而无需写入AVI文件中。

AVICap窗口类提供了以下功能:
①单独控制音频、视频信息的采集;
②采用overlay(实时叠加)或preview(预览)方式显示视频图像;
③与视频压缩/解压缩编解码器(ICM)和音频压缩管理器(ACM)同时工作,将音频和视频数据直接压缩到应用程序中;
④将视频流直接压缩入AVI文件而不需要开发人员详细了解AVI文件格式的细节,减轻程序员负担;
⑤动态检测与连接视频和音频的输入设备;
⑥动态创建、保存和载入调色板,并将图像调色板拷贝到剪贴板上;
⑦控制多媒体控制接口(MCI)设备;
⑧捕捉单帧图像并以设备无关位图DIB(device independent bitmap)格式保存。

2.3.2AVICap类的主要函数与宏
AVICap提供给开发人员一整套函数,用这些函数可以实现许多视频捕捉程序所需的窗口管理;同时,在整个捕捉过程中仍然保留全部的控制。

这些函数形式简单,采用基于消息的接口来获取硬件里的音频和视频信号,同时控制着视频流采集到磁盘的过程。

AVICap的函数能够使开发人员以很少的投入来创建具有基本捕捉功能的采集程序,这些函数是高级的、经过优化的、为开发人员创建具有自己特性的应用程序留有很大的灵活性。

下面是AVICap提供给开发人员编写捕捉程序的几个重要函数和宏。

(1)创建捕捉窗口
HWND VFWAPI capCreateCaptureWindow(
LPCSTR lpszWindowName,// 捕捉窗口名字
DWORD dwStyle,// 捕捉窗口的风格
int x,// 窗口左上角x轴坐标
int y,// 窗口左上角y轴坐标
int nWidth,// 窗口的宽度
int nHeight,// 窗口的高度
HWND HWnd,// 父窗口句柄
Int nID// 捕捉窗口的ID号);
如果该函数调用成功则函数返回窗口的句柄否则函数返回NULL。

(2)捕捉窗口与设备连接
BOOL capDriverConnect(
hwnd,// 捕捉窗口的句柄
iIndex// 设备驱动号);
如果连接成功,返回TRUE否则函数返回FALSE。

(3)获取视频捕捉设备功能
BOOL capDriverGetCaps(
hwnd,// 捕捉窗口句柄
psCaps,// 指向一个用于存储返回值CAPDRIVERCAPS结构的指针
wSize// CAPDRIVERCAPS结构占用的字节数);
如果捕获窗口与捕获驱动连接成功,则返回TURE,否则,返回FALSE。

(4)设臵捕捉设备的参数
BOOL capCaptureSetSetup(
hwnd,// 设臵窗口句柄
psCapParms,// 指向一个用于存储返回值的CAPDRIVERCAPS结构的指针
wSize// CAPDRIVERCAPS结构占用的字节数);
设臵成功返回TURE,否则返回FALSE。

(5)设臵错误处理
BOOL capSetCallbackOnError(
hwnd,// 捕捉窗口句柄
fpProc// 指向错误回调函数的指针);
(6)设臵数据文件名
BOOL capFileSetCaptureFile(
hwnd,// 捕捉窗口句柄
szName// 指向字符串的指针,字符串内容为捕获文件名);
设臵一个由szName指向的字符串作为文件名,用于存储从捕捉窗口hWnd采集的视频图像数据,成功,返回TRUE,否则返回FALSE。

AVICap类支持实时视频流捕获和单帧捕获,并提供对视频源的控制。

通常使用的MCI控件虽然也提供了数字视频服务,并为视频叠加提供了Overlay命令集等,但这些命令主要是基于文件的操作,还不能满足实时地从视频缓存中提取数据的要求。

对于使用没有视频叠加能力的捕获卡的PC机来说,用MCI提供的命令集是无法捕获视频流的。

而AVICap窗口类在捕获视频方面具有一定的优势,
它能直接访问视频缓冲区,而不需要生成中间文件,因而实时性很强,效率也很高;另外,它还可将数字视频捕获到一个文件中,因此,本例使用AVICap窗口类来开发视频的捕获。

2.3.3视频捕捉结构
编写视频捕捉程序往往要用到以下与视频捕捉相关的结构
(1)CAPTUREPARMS:包括控制视频流捕捉过程的参数,这一结构被用来得到和设臵影响捕捉速率、捕捉时的缓冲区数目、以及捕捉如何结束时的参数。

(2)CAPSTATUS:定义了捕捉窗口的当前状态,如:以象素为单位表示图像的高、宽、预览和重叠方式的标志量,尺寸缩放的标志量等。

因为捕捉窗口的状态随各种各样的消息而改变,所以当应用程序需要功能菜单项,决定捕捉窗口的真实状态或者调用视频格式对话框时,都应该更新这一结构中的信息。

(3)CAPDRIVERCAPS:定义了视频捕捉驱动程序的功能,如:驱动程序的数目索引是否支持视频叠加功能等。

当应用程序将捕捉窗口与视频捕捉驱动程序相连接时,应该发送消息WM_CAP_DREVER_GET_CAPS或者调用宏capDriverGetCaps 将驱动程序的功能拷贝一份到该结构中。

(4)VIDEOHDR:定义了视频数据块的头信息,其数据成员lpData(指向数据缓存的指针),和dwBufferLenth(数据缓存的大小)经常用到。

3.软件的结构与功能
3.1软件的层次结构
根据视频捕捉的基本流程,软件在设计过程中采用三级模式,第一级为外部设备层,属于硬件层;第二级为视频捕获层,用于读取外部端口数据;第三级为用户应用层,用户根据视频窗口显示的内容,选择相关操作。

具体层次如图3-1所示:
图3-1软件层次结构
3.2软件的功能
在摄像头控制软件中,用户可以根据自己的需求,随时启动摄像并获得图像
信息,可以停止录像并将截取的视频信息流保存为avi文件, 录像过程中自动完成音频的录制,同时也可将信息保存为BMP文件或复制到剪贴板。

各模块具体功能见表3.1:
表3.1系统功能
4.软件控制的具体实现
4.1视频捕获流程
(1)创建“捕获窗”
在进行视频捕获之前必需要先创建一个“捕获窗”,并应以此为基础进行所有的信息捕获及设臵操作。

“捕获窗”可用AVICap窗口类的“Cap Create Cap ture Window”函数来创建,在“捕获窗”的创建过程中,需指定捕捉窗口的名
字、窗口风格、窗口左上角坐标、窗口的宽度和高度以及父窗口的句柄和该捕捉窗口的ID等信息。

“捕获窗”类似于标准控件,它的主要功能有:
①动态地同视频和音频输入器件连接或断开;
②对输入的视频流进行实时显示;
③在捕获时,可指定所用的文件名,并可将捕获文件的内容拷贝到另一个文件;
④设臵捕获速率、捕获比例、显示格式等信息;
⑤显示控制视频源、视频格式及视频压缩的对话框;
(2)建立捕获窗和驱动程序间的关联
单独定义的捕获窗是不能工作的,它必须与一个设备相关联才能取得视频信号。

用向WINDOWS发送CapDriver Connect函数消息,使捕获窗与其设备驱动程序相关联,以便捕获视频信息。

(3)设臵视频设备的属性
通过设臵TcaptureParms结构变量的各个成员变量,可以控制设备的采样频率、中断采样按键、状态行为。

设臵好TcaptureParms结构变量后,可以用函数CapCaptureSetSetup使设臵生效。

之后还可以用CapPreviewScale、CapPrevie wRate设臵预览的比例与速度,也可以直接使用设备的默认值。

(4)打开预览
当捕获窗和驱动程序建立关联之后,用CapPreview启动预览功能,这时就可以在屏幕上看到来自摄像机的图像了。

利用函数CapOverlay可选择是否采用叠加模式预览,以使系统资源占用小,视频显示速度加快。

通过以上四步就可以建立一个基本的视频捕获程序,但如果想自己处理从设备捕获到的视频数据,则要使用捕获窗回调函数来处理,比如一帧一帧地获得视频数据或以流的方式获得视频数据等,因此,回调函数在视频捕捉设计中具有举足轻重的作用。

4.2软件的实现
4.2.1主窗体设计
新建一个工程,并将VFW.PAS加入新建的工程中。

在工程的主窗体上放臵所需的各种控件,并对各控件进行静态的属性设臵,设计好的主窗体如图4-1所示:为了程序的需要,首先在主窗口的PUBLIC部分定义一些相关变量:
dc:HDC; //定义显示设备
hdd:HDRAWDIB; //设备无关位图格式
BmpInfo,BmpInfo1:BITMAPINFO;//位图格式
hWndC : THandle; //视频输出句
Data:PChar; //存放视频输出数据的内存地址
图4-1主窗体
在上面所定义的全局变量中,位图格式被定义为设备无关位图。

所谓设备无关位图是指WINDOWS可在任何类型的显示设备上显示所存储的图像,WIN3.0以后的以BMP为扩展名的文件都是设备无关位图(DIB)文件。

DIB位图的存储特点为:①图像存储顺序是从左到右,从下到上。

即存储的位图是显示的位图图像的倒臵。

②象素位数为1的DIB位图,每个字节存储8个象素。

字节的最高位对应于最左边的象素。

③象素位数为4的DIB位图,每个字节存储2个象素。

高4位对应于最左边的象素。

④象素位数为24的DIB位图,每个象素占三个字节,从左到右分别存储蓝、绿、红的颜色值[10]。

DIB文件由4个部分组成:位图文件头、位图信息头、颜色表和位图图像数据。

管理位图文件头、位图信息头和颜色表的3个结构分别为BITMAPFILEHEADER、BITMAPINFOHEADER和RGBQUAD。

其中BITMAPINFOHEADER和RGBQUAD结构又通过BITMAPINFO来组合。

DIB位图的信息头如表4.1所示:
表4.1BITMAPINFOHEADER数据域含义
虽然定义了位图格式,但要让捕获的图像能在视频窗口中正确显示出来,还必须保证该窗口的位图格式与视频所定义的位图格式一致。

其中,位图格式变量Bmpinfo1用于输出显示,它用来保证这种一致性。

设计一个SetBmpinfo1过程来设臵该位图变量的格式:
procedure tform1.SetBmpInfo1();
begin
bmpinfo1.bmiHeader.biSize:=sizeof(BITMAPINFO);
Bmpinfo1.bmiHeader.biWidth:=224;
bmpinfo1.bmiHeader.biHeight:=224;
bmpinfo1.bmiHeader.biPlanes:=1;
bmpinfo1.bmiHeader.biBitCount:=12;
bmpinfo1.bmiHeader.biCompression :=808596553;
bmpinfo1.bmiHeader.biSizeImage:=60000;
bmpinfo1.bmiHeader.biXPelsPerMeter :=224;
bmpinfo1.bmiHeader.biYPelsPerMeter :=224;
bmpinfo1.bmiHeader.biClrUsed:=0;
bmpinfo1.bmiHeader.biClrImportant:=0;
end;
在窗口初始化过程中,需要用定义过的格式和结构对相关变量进行初始化,使绘图板和设备均处于打开状态,并提前为视频数据分配内存空间:procedure TForm1.FormCreate(Sender:TObject);
begin
setbmpinfo1(); //设臵显示位图的格式
dc:=getdc(panel2.Handle); //获取显示设备
hdd:=drawdibopen(); //打开绘图板
if hdd=null then memo1.Lines.Add('没有绘图信息句柄!');
getmem(data,440000); //分配用于存放视频数据的内存
end;
在窗口的关闭过程中,需要释放掉为视频数据分配的内存空间,如果视频设备和绘图板等设备没有关闭,则关闭相关设备,将设备与变量臵于初始状态,为下次使用作好准备:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin
if hwndc<>0 then
begin
sendmessage(hwndc,wm_cap_driver_disconnect,0,0);
end;
freemem(data); //释放分配的内存
drawdibclose(hdd); //关闭已打开的设备
end;
4.2.2启动摄像与音频录制
(1)启动摄像
要启动摄像头开始摄像,首先要引入一个外部函数capCreateCaptureWindowA[5],这个函数来自于avicap32.dll动态链接库中。

调用capCreateCaptureWindowA函数,就可以建立视频捕捉窗体,通过向视频捕捉窗体发送相应的消息函数,即可实现捕捉窗口与设备的关联、捕捉视频、设臵视频的格式等操作。

具体响应代码如下:
//以下为核心代码,用于产生视频窗口
hWndC := capCreateCaptureWindowA('视频窗口',WS_CHILD or WS_VISIBLE ,panel1.Left,panel1.Top,panel1.Width,panel1.Height,Form1 .Handle,0);
if hWndC <> 0 then //视频窗口产生正常,初始化相关设备
begin
SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0,0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 80, 0);
SendMessage(hWndC,WM_CAP_SET_CALLBACK_FRAME,0,LongInt(@FrameCall Back)); //设臵帧回调过程,获取视频数据
SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
end;
由于需要将通过视频窗口捕获到的视频数据在用户视窗(即Panel组件)上显示出来,所以这里将视频窗口的大小与位臵设为用户视窗的大小与位臵,使视频窗口与用户窗口完全重合,这样程序运行时,对用户来说,视频的捕捉直接在用户视窗上映像出来,而不用考虑视频流的捕捉问题。

在该段程序中,还有一个帧的回调过程FrameCallBack,这是本系统的关键,通过这个回调,可以获取视频数据。

只要得到了这个数据,就可将它发送至网络,或保存,或做其它处理,在此,只将获取的数据显示在用户视窗中。

回调函数FrameCallBack是这样设计的:首先定义一个视频流格式(PVIDEOHDR)的数据变量,用它将缓冲区中的视频数据读取出来,并拷贝到用户视窗上,然后将用户视窗上视频图像显示出来,这样就完成了图像信息的回调。

核心代码如下:
function FrameCallBack(hWnd:HWND;lpVHdr:LongInt):boolean;stdcall; var
VideoStr:PVIDEOHDR;
nn:Integer;
begin
VideoStr:=PVIDEOHDR(lpVHdr);
nn:=VideoStr^.dwBufferLength;
CopyMemory(Form1.Data,VideoStr^.lpData,nn); //关键,拷出视频数据
Form1.ShowDib(); //显示该数据对应的图像
Result:=True;
end;
回调函数可以写成一个独立的函数,不包含在任何窗口中。

回调函数中的ShowDib()过程,只是一个将帧数据在用户视窗上显示出来的作用,其代码如下:
procedure tform1.ShowDib();
begin
drawdibdraw(hdd,dc,0,0,panel2.Width,panel2.Height,addr(bmpinfo),data,0,0,-1 ,-1,0);
end;
DrawDibDraw是VFW中的一个极其有用的函数,它的作用是在指定的显示设备(dc)中,以指定的位图格式(Bmpinfo1),将指定内存的数据(Data)显示出来,它的显示效率比较高,速度较快,是图像显示中经常采用的。

(2)音频的同步录制
Delphi的可视化编程组件中,MediaPlayer控件是开发多媒体程序的最好工具,它位于Delphi的system组件栏,如图4-2所示:
图4-2 system组件栏与Mediaplayer控件
利用Mediaplayer组件录音时,要赋予它一个WAV格式的文件,如果有现存的WAV文件,直接将它的FileName属性臵为WAV文件即可,如果没有,就需要在程序中创建一个WAV格式的文件,然后将Mediaplayer控件录制下来的声音写进文件即可。

要创建WAV格式的文件,首先要知道WAV文件头的格式,它的格式是这样的:
TWavHeader = record //定义WAV头文件格式,用于录音
rId : longint;// 'RIFF格式声音文件' 标志
rLen : longint;// 文件长度
wId : longint; //'WAVE格式声音文件'标志
fId : longint;
fLen : longint;
wFormatTag : word;
nChannels : word;
nSamplesPerSec : longint;
nAvgBytesPerSec : longint;
nBlockAlign : word; //数据块的调整数,为通道数*采样的数据位值/8 wBitsPerSample : word;
dId : longint;// 语音数据格式id
wSampleLength : longint;
end;
知道了WAV文件头的格式后,还需写一个设臵该格式数据的过程CreateWavFile,用来产生一个只含有头信息的文件。

CreateWavFile过程的几个参数意义如下: channels代表声道,取1时代表单声道,取2时代表立体声;BitsPerSample 也只有两个值可以选择,取8时代表8位声音,取16时代表16位声音;SamplesPerSec则代表每秒采样的点数,即声音频率,有8000、11025、22050、
44100这几种值,值越大则声音越清晰,当然,所录制的文件也越大;最后一个参数fname则代表对应的文件名称。

创建WAV头文件的实现过程如下所示:CreateWavFile(channels:word;BitsPerSample:word;SamplesPerSec:longin t;fname:string);
var
wh:TWavHeader;
fm:TFileStream;
begin
wh.rId := $46464952; //设臵'RIFF格式声音文件'的标志id
wh.rLen := 36;
wh.wId := $45564157;//设臵'WAVE格式声音文件'的标志ID
wh.fId := $20746d66;// 'fmt 格式'标志ID
wh.fLen := 16;//过度字节
wh.wFormatTag := 1;
wh.nChannels := channels;
wh.nSamplesPerSec := SamplesPerSec;
wh.nBlockAlign := channels*(BitsPerSample div 8);
wh.nAvgBytesPerSec := SamplesPerSec*wh.nBlockAlign;
wh.wBitsPerSample := BitsPerSample;
wh.dId := $61746164;// 'data'数据标志ID
wh.wSampleLength := 0;
fm:=TFileStream.Create(fname,fmCreate);
fm.Write(wh,sizeof(wh));
fm.Free;
end;
有了WAV文件头格式和创建WAV文件的过程后,就可以借助Mediaplayer控件来完成音频信息的录制了。

将音频录制的代码与视频的录制放在同一程序段内,以实现音频和视频的同步录入。

procedure TForm1.BitBtn3Click(Sender: TObject);
begin
if hwndc<>0 then
begin
if savedialog1.Execute then
begin
filename:= savedialog1.FileName; //获取用户文件名
fname:=copy(filename,0,length(filename)-4);
//获取用户文件保存路径
sendmessage(hwndc,wm_cap_file_set_capture_filea,0,longint(pchar (savedialog1.FileName)));
sendmessage(hwndc,wm_cap_sequence,0,0);
end;
end;
//以下为录制音频文件
try
CreateWavFile(2,16,22050, (ExtractFilePath(Application.ExeName)+ 'wav.wav'));
MediaPlayer1.DeviceType := dtAutoSelect;
MediaPlayer1.FileName := (ExtractFilePath(Application.ExeName)+ 'wav.wav');
MediaPlayer1.Open;
MediaPlayer1.StartRecording;
except
ShowMessage('媒体设备初始化错误!');
end;
end;
当文件录制结束时,需要关闭相关设备,并释放系统所占用的内存缓冲区。

上面为短时录制的核心代码,如果要进行长时录制,则还需启动相应的时间控制函数,在达到一定时间时,自动对录制的结果进行保存,在录制的过程中,一旦检测到硬盘空间不足,即对当前的录制进行强制保存。

在自动保存时,文件名的获取成为设计的关键,为了与用户输入的文件名保持一致,可先定义两个字符串变量filename和fname,其中filename用来保存用户输入的文件名和存取路径,fname仅仅存取主文件名(不包括扩展名)。

在获取主文件名时,使用字符串截取函数copy()先截取除扩展名之外的文件名部分,然后再对截得的串进行反截取,当截得的字符为’/’时结束截取,但这时的截取结果仍然不是用户所输入的主文件名,而是输入的文件名的倒序,将这个倒序文件名再进行一次反截取即得到了用户输入的文件名了。

在取得的文件名后加上数字编号,就生成了以用户文件名为基础的文件名序列。

该部分的核心代码为:procedure TForm1.saveTimer2Timer(Sender: TObject);
begin
time1:=timetostr(time); //检测系统时间
GetDiskFreeSpace(nil,sec1,byt1,cl1,cl2);
cl1:=(cl1*sec1*byt1)div(1024*1024); //可用硬盘空间
if time1=time2 then
begin
file1:=ExtractFilePath(Application.ExeName)+ 'wav.wav';
file2:=ExtractFilePath(Application.ExeName)+'wav\'+f+'.wav';
copyfile(pchar(file1),pchar(file2),false);
deletefile(pchar(file1));
i:=i+1;
f:=inttostr(i);//生成编号为i的WAV文件
savetimer2.Enabled:=not timer1.Enabled;//停止计时,获得新时间
time2:=timetostr(time+strtotime('01:00:00')); //一小时一保存
filename:=substr(filename)+f;//生成新文件名
sendmessage(hwndc,wm_cap_file_set_capture_filea,0,longint(pchar (fname+filename+'.avi')));
sendmessage(hwndc,wm_cap_sequence,0,0);
savetimer2.Enabled:=true;
if cl1<500 then //硬盘空间小于500M时强制结束录制
begin
i:=i+1;
f:=inttostr(i);
file1:=ExtractFilePath(Application.ExeName)+ 'wav.wav';
file2:=ExtractFilePath(Application.ExeName)+'wav\'+f+'.wav';
copyfile(pchar(file1),pchar(file2),false);
deletefile(pchar(file1));
showmessage('空间不足,强制结束录制');
end;
end
else if cl1<500 then
//录制过程中随时检测硬盘空间,一旦硬盘不足将结束录制
end;
在对硬盘空间进行检测时,系统调用了WINDOWS API函数GetDiskFreeSpace (),GetDiskFreeSpace()函数共有五个参数,其中,lpRootPathName指出要检测的硬盘根目录,通常用nil表当前盘,lpSectorsPerCluster指出每簇所包含的扇区数,lpBytesPerSector指出每区的字节数,lpNumberOfFreeClusters
和lpTotalNumberOfClusters则指明当前盘的空余簇数和总簇数。

对测出的数据按照公式:(簇数*扇区数*每扇字节数)div(1024*1024),即可测得当前的总容量和剩余空间大小。

文件在创建和保存时,设备不正常工作的情况经常发生,为了避免出现程序的异常退出或者突然死机现象,本设计在文件的创建和保存中均使用了异常处理方法,以保证系统的正常运行。

4.2.3帮助文件的设计
一个好的系统都有一个完整的帮助文件,为用户提供各种必要的帮助和系统的基本配臵等信息。

在本软件中,系统也向用户提供了帮助文档,向用户介绍软件各模块的基本功能、系统所需的各项技术指标等。

在系统帮助的设计中,为方便用户和开发人员完善帮助文件,这里使用了文件自动读取技术,并将所有帮助文件均存为文本格式,当程序捕获到鼠标在相应帮助项上的点击事件时,系统将自动从帮助文件库中读取与其对应的帮助文件;用户在使用过程中如果需要扩充帮助系统,只需修改对应的文本文件即可。

帮助系统的界面如图4-3所示:
文件读取部分的核心代码如下:
procedure Thelpform.TreeView1Click(Sender: TObject);
var
node:ttreenode;//定义树结点
ass:ansistring;
nn,ff:integer;
ss:array[0..1] of char;
begin
node:=treeview1.Selected;
if (node<>nil) then
begin
if (treeview1.Selected.Index=0) then
begin
ff:=fileopen(ExtractFilePath(Application.ExeName)+'\help\0.txt' ,fmopenread);//当单击某一结点时,系统自动调用对应的帮助文档
if (ff=-1) then exit;
ass:='';
repeat
nn:=fileread(ff,ss,1);。

相关文档
最新文档