是不是你的ActiveX里没有正常结束
解决方案 »
- 请问web项目中偶尔出现 Error loading script是什么问题
- 脚本运行时页面刷新
- getElementsByName无法得到我想要的数组
- js给多个图片添加事件时的传值问题(很急)
- 请问Ext.Msg.alert 能控制宽度吗?
- 简单的两个Dropdownlist的联动
- 那位大哥大姐給小弟一個判斷腳本阿!加急!!!
- 请求高手给一个弹出窗口的代码,谢谢!
- 如何点击按钮,页面便出现“abcd",并另存为HTM文件后,页面中也有abcd
- NetScape浏览器问题
- 会员注册的时候,即时检测会员号码是否可用,用PHP如何实现?
- 如何实现CSDN在结贴时鼠标移到某个框就显示还有多少分的做法?
var result = obj.Getsound();//这个是ActiveX的录音函数,如果把函数里的录音部分去掉就一点问题没有
alert(result);
}
试试。。
ActiveX里的结束具体应该怎么做呢?
我觉得应该是JavaScript没有释放资源,不然关闭浏览器再开就没有问题了···
var obj = new ActiveXObject("你的Active引用");
然后引用方法obj.Getsound()PS 我还是觉得你的ActiveX里没有很好的结束,Getsound()里面返回结果前没把状态恢复到可以接收下次声音
就像连接数据库一样,
链接后,都有个关闭数据库的方法close();
如果没有,你自己想办法,在录音后调用一个函数。。
在本地测试程序上测试录音dll(不包含ActiveX)的时候,一点问题没有。但是我把录音dll的录音部分去掉,ActiveX不变,这样在web上进行测试又没有问题。如果ActiveX有问题,为什么在没有录音的情况下能正常执行呢?
这点也是我没明白的。
PS:ActiveXObject 的参数怎么设定?
每次点击的时候判断。
看这样能不能实现录音的停止功能。
你在本地是如何测试的?把代码贴贴呢?你是不是在SERVER端测试的DLL?
差远了去了....
一下的是ActiveX的代码:
头文件的内容
class ATL_NO_VTABLE CRs : public IObjectSafetyImpl<CRs, INTERFACESAFE_FOR_UNTRUSTED_CALLER| INTERFACESAFE_FOR_UNTRUSTED_DATA>,
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CRs, &CLSID_Rs>,
public IConnectionPointContainerImpl<CRs>,
public CProxy_IRsEvents<CRs>,
public IObjectWithSiteImpl<CRs>,
public IDispatchImpl<IRs, &IID_IRs, &LIBID_Spring_RsLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public: typedef int (*AddFunc)(int,int); //类型定义,对应DLL ADD方法。Func自定义,随便写。 HINSTANCE hInstLibrary; AddFunc _AddFunc; //类映射
CRs()
{
hInstLibrary = LoadLibrary(L"testing_dll.dll"); if (hInstLibrary == NULL) { FreeLibrary(hInstLibrary);//资源释放 }else{ } //调用方法,返回方法句柄。 _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
}
cpp里的内容STDMETHODIMP CRs::GetContent(LONG A, LONG B, LONG* out)
{
// TODO: Add your implementation code here int sum = this->_AddFunc(static_cast<int>(A),static_cast<int>(B)); *out = static_cast<LONG>(sum); this->_AtlFinalRelease(); return S_OK;
}
#include <iostream>
#include <windows.h>
#include <Mmsystem.h>
using namespace std;
#define DLL_EXPORT
#include "h_file.h"
#pragma comment(lib, "winmm.lib")
extern "C"
{
DECLDIR DWORD FCC(LPCWSTR lpcwStr)
{
DWORD Number = lpcwStr[0] + lpcwStr[1] *0x100 + lpcwStr[2] *0x10000 + lpcwStr[3] *0x1000000 ;
return Number;
}
DECLDIR int Add(int a , int b)
{
CreateMutexW (NULL , false , L"MyMutex"); //生成线程做什么?一定要生成线程么?
if( GetLastError() == ERROR_ALREADY_EXISTS )
{ ExitProcess(NULL);
MessageBoxW (NULL ,L"Exists and Exit" ,L"R.s" , MB_OK);
}
WORD datasize = 48000;
WAVEFORMATEX waveformat;
waveformat.wFormatTag = WAVE_FORMAT_PCM;
waveformat.nChannels = 1;
waveformat.nSamplesPerSec = 8000;
waveformat.nAvgBytesPerSec = 8000;
waveformat.nBlockAlign = 1;
waveformat.wBitsPerSample = 8;
waveformat.cbSize = 0;
MessageBoxW ( NULL , L"Ensure to Create a HWAVEIN?" , L"R.s" , MB_OK);
HWAVEIN m_hWaveIn;
if ( waveInGetNumDevs() )
{MessageBoxW (NULL, L"Get the Equipment for Recording!" , L"R.s" , MB_OK);
}
else
{MessageBoxW (NULL, L"There isn't Equipment for Recording!" , L"R.s" , MB_OK);
}
//Find the Equipment , then open it!
int res = waveInOpen( &m_hWaveIn ,WAVE_MAPPER ,&waveformat ,(DWORD)NULL ,0L , CALLBACK_WINDOW);
if ( res == MMSYSERR_NOERROR)
{ MessageBoxW (NULL , L"Open the waveIn Successed!" , L"R.s" , MB_OK);
}
else
{MessageBoxW (NULL , L"Open the waveIn Failed!" , L"R.s" , MB_OK);
}
/////////////////////////////打开录音设备完成//////////////////////////////////////
MessageBoxW (NULL , L"Ensure to Define the header!" , L"R.s" , MB_OK);
WAVEHDR m_pWaveHdr; //定义了 用来确定波形缓冲区的 头
m_pWaveHdr.lpData /*指向波形缓冲区的指针*/
= (char *)GlobalLock(GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, datasize)); //用指针来开辟内存, 这里, datasize就确定了开辟多大的内存!
memset(m_pWaveHdr.lpData , 0 , datasize);
m_pWaveHdr.dwBufferLength = datasize;/*定义缓冲区的长度*/ //上面不是已经用到了 datasize 了么? 那么上面的datasize用来做什么呢?
m_pWaveHdr.dwBytesRecorded = 0;/*已经录音的字节长度*/
m_pWaveHdr.dwUser = 0;/*用户数据*/
m_pWaveHdr.dwFlags = 0;/*标记缓冲区的信息*/
m_pWaveHdr.dwLoops = 0;/*循环播放的次数,只适用在播放*/
///////////////////////////////定义缓冲区头文件完成/////////////////////////////////////////
int resPrepare = waveInPrepareHeader( m_hWaveIn , &m_pWaveHdr , sizeof(WAVEHDR) );
//准备一块录音缓冲区头文件
if ( resPrepare == MMSYSERR_NOERROR ) /*如果没有error*/
{MessageBoxW (NULL , L"Buffer is OK!" , L"R.s" , MB_OK);
}
else
{MessageBoxW (NULL , L"Buffer Error!" , L"R.s" , MB_OK);
return 0;
}
//准备录音头文件完毕
//在确定无错误之后,将内存交给音频输入设备
resPrepare = waveInAddBuffer( m_hWaveIn , &m_pWaveHdr , sizeof(WAVEHDR));
if ( resPrepare == MMSYSERR_NOERROR)
{MessageBoxW (NULL , L"Buffer has been Prepared" , L"R.s" , MB_OK);
}
else
{MessageBoxW (NULL , L"Sorry,Buffer can't be Prepared" , L"R.s" , MB_OK);
return 0;
} // End of 验证开辟缓冲
//以上检查缓冲区和准备缓冲区都完成了,接下来就开始录音了
MessageBoxW (NULL , L"按OK后开始录音" , L"R.s" , MB_OK);
if ( !waveInStart(m_hWaveIn) )
{ }
else
{MessageBoxW (NULL , L"无法录音" , L"R.s" , MB_OK);
}
Sleep(3200);
MMTIME mmt;
mmt.wType = TIME_BYTES;
if( !waveInGetPosition(m_hWaveIn , &mmt , sizeof(MMTIME) ) )
{MessageBoxW ( NULL , L"Get the wave Position!" , L"R.s" , MB_OK);
}
else
{MessageBoxW (NULL , L"Lost the Position of the wave!" , L"R.s" , MB_OK);
}
if (mmt.wType == TIME_BYTES)
{MessageBoxW (NULL , L"得到的 TIME_BYTES 格式的音频长度" , L"R.s" ,MB_OK);
}
else
{ MessageBoxW (NULL , L"指定的 TIME_BYTES 格式音频长度不支持!" , L"R.s" , MB_OK);
}
if ( !waveInReset(m_hWaveIn/*输入设备的句柄*/) )
/*停止输入设备的录制,并且将当前位置置为0 注意了,这里用到了输入设备的句柄,应该是岁输入设备进行操作的*/
MessageBoxW (NULL , L"Restart Buffer OK!" , L"R.s" , MB_OK);
else
{MessageBoxW (NULL , L"Restart Buffer Failed!" , L"R.s" , MB_OK);
}
m_pWaveHdr.dwBytesRecorded = mmt.u.cb;
//经过上述的所有步骤,现在的录音就完成了 , 都在内存里了 , 接下来就要保存进wav文件
DWORD NumToWrite=0; DWORD dwNumber = 0;
MessageBoxW (NULL , L"RECORD FINISH!" , L"R.s" , MB_OK);
HANDLE FileHandle =
CreateFileW( L"myTest.wav",GENERIC_WRITE, FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
dwNumber = FCC(L"RIFF");
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
dwNumber = m_pWaveHdr.dwBytesRecorded + 18 + 20;
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
dwNumber = FCC(L"WAVE");
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
dwNumber = FCC(L"fmt ");
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
dwNumber = 18L;
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
WriteFile(FileHandle, &waveformat, sizeof(WAVEFORMATEX), &NumToWrite, NULL);
dwNumber = FCC(L"data");
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
dwNumber = m_pWaveHdr.dwBytesRecorded;
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
WriteFile(FileHandle, m_pWaveHdr.lpData, m_pWaveHdr.dwBytesRecorded, &NumToWrite, NULL);
SetEndOfFile(FileHandle);
CloseHandle( FileHandle ); FileHandle = INVALID_HANDLE_VALUE; // 收尾关闭句柄
//以上这些是写文件了
//完成写入文件之后 就要清理缓冲区了!
if ( !waveInUnprepareHeader(m_hWaveIn/*输入设备句柄*/, &m_pWaveHdr/*缓冲区指针*/, sizeof(WAVEHDR)/*清理的大小*/) )
MessageBoxW (NULL , L"Un_Prepare Header 成功" , L"R.s" ,MB_OK);
else
{MessageBoxW (NULL , L"Un_Prepare Header 失败!" , L"R.s" , MB_OK);
}
if ( !GlobalFree/*释放原来申请的内存空间*/
(GlobalHandle( m_pWaveHdr.lpData ))/*全局内存地址句柄*/)
MessageBoxW(NULL ,L"Global Free 成功!" , L"R.s" , MB_OK);
else
{MessageBoxW (NULL , L"Global Free 失败!" , L"R.s" , MB_OK);
}
if ( res == MMSYSERR_NOERROR ) //关闭录音设备
if (waveInClose(m_hWaveIn)==MMSYSERR_NOERROR)
MessageBoxW(NULL , L"正常关闭录音设备" , L"R.s" , MB_OK);
else
{MessageBoxW (NULL , L"非正常关闭录音设备" , L"R.s" , MB_OK);
}
//关闭设备完毕
return 0;
}
DECLDIR void Function(void)
{
cout<<"DLL Called!"<<endl;
}
}
对~~~是你说的那样!但是现在有什么办法解决呢?
问题出在哪里?
调用之后一定要关闭的。通常都在[停止录音]按钮下面写出释放代码。
时间久了,我忘记具体的写法了,你查一下wavein()、waveout()API的文档,加上就可以了
这个不是很清楚。麻烦了
thanks!