是不是你的ActiveX里没有正常结束

解决方案 »

  1.   

     function doTest() {        var obj=document.getElementById("Lsy");
              var result = obj.Getsound();//这个是ActiveX的录音函数,如果把函数里的录音部分去掉就一点问题没有 
              alert(result); 
        } 
    试试。。
      

  2.   

    你的意思是说 ActiveX里没有正常结束?
    ActiveX里的结束具体应该怎么做呢?
      

  3.   

    还是···不行···有别的办法么?
    我觉得应该是JavaScript没有释放资源,不然关闭浏览器再开就没有问题了···
      

  4.   

    要不你试下每次点击时创建一次新对象
    var obj = new ActiveXObject("你的Active引用");
    然后引用方法obj.Getsound()PS 我还是觉得你的ActiveX里没有很好的结束,Getsound()里面返回结果前没把状态恢复到可以接收下次声音
      

  5.   

    应该和开始录音的方法相反,
    就像连接数据库一样,
    链接后,都有个关闭数据库的方法close();
    如果没有,你自己想办法,在录音后调用一个函数。。
      

  6.   

    ActiveX构成是这样的,写了一个录音的dll,然后ActiveX影射录音dll里的方法,
    在本地测试程序上测试录音dll(不包含ActiveX)的时候,一点问题没有。但是我把录音dll的录音部分去掉,ActiveX不变,这样在web上进行测试又没有问题。如果ActiveX有问题,为什么在没有录音的情况下能正常执行呢?
    这点也是我没明白的。
    PS:ActiveXObject 的参数怎么设定?
      

  7.   

    给Getsound()添加一个全局参数,最好是常用类型。。
    每次点击的时候判断。
    看这样能不能实现录音的停止功能。
      

  8.   

    如果对声卡的操作不关闭的话,我在本地用程序对录音的dll进行测试,为什么又能多次正常录音呢?这点我觉得很奇怪···还有别的可能的原因么?
      

  9.   


    你在本地是如何测试的?把代码贴贴呢?你是不是在SERVER端测试的DLL?
      

  10.   

    你的DLL是如何实现录音的?是用底层函数写的,还是简单的调用表层API实现的?两者之间无论是效果还是稳定性都
    差远了去了....
      

  11.   

    我的做法是在一个dll里调用win32 API的wave函数, 然后用ActiveX调用这个dll 然后再把ActiveX放进web里,测试的是录音的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;
    }
      

  12.   

    接下来的是录音的函数了,就是在录音的dll里面。这些就是源代码了,我只是多加了一个加法函数进行别的测试。请指点:
    #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;
        }
    }
      

  13.   

    对!我突然想明白为什么了!我测试的是利用控制台,每次测试之后就会关闭了,自然就释放资源了!但是在web上一直没有关闭,肯定就没有释放!
    对~~~是你说的那样!但是现在有什么办法解决呢?
    问题出在哪里?
      

  14.   

    呵呵,是这个问题。
    调用之后一定要关闭的。通常都在[停止录音]按钮下面写出释放代码。
    时间久了,我忘记具体的写法了,你查一下wavein()、waveout()API的文档,加上就可以了
      

  15.   

    大致看了一下你的DLL代码,还是个“raw code”。容错、格式转换都没做。特别是容错,这样的应用没更详细的容错机制是不稳定的,例如,机器无声卡,有声卡但驱动错误,声卡被独占等等还有就是格式转换,建议你加上MP3格式,否则没有实用价值,呵呵
      

  16.   

    这个dll只是最初用来测试的,呵呵,是的,你说的那些都没有呢,是打算一层一层做,所以这个dll基本上没有任何容错功能。改进ing呵呵,先把资源的问题处理掉。对了,还想问你一些东西,就是我释放资源应该是在web里释放还是在ActiveX里还是在dll里直接最声卡资源进行释放?
    这个不是很清楚。麻烦了
      

  17.   

    web里释放的仅仅对象所占内存;功能上的释放所谓的资源当然是在DLL里面
      

  18.   

    好的,太感谢了!
    thanks!
      

  19.   

    有一点不明白···直接在录音的 dll 里加函数就能将 资源释放掉么?