首页前端开发HTML捕获电脑的声音放到手机播放

捕获电脑的声音放到手机播放

时间2024-01-25 11:54:26发布访客分类HTML浏览350
导读:收集整理的这篇文章主要介绍了html5教程-捕获电脑的声音放到手机播放,觉得挺不错的,现在分享给大家,也给大家做个参考。小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 在Pc上使用adb命令:ad...
收集整理的这篇文章主要介绍了html5教程-捕获电脑的声音放到手机播放,觉得挺不错的,现在分享给大家,也给大家做个参考。小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

在Pc上使用adb命令:adb forward tcp:4626 tcp:4883,在PC上建立4626端口通信数据将被重定向到手机端server的4883端口;然后初始化socket,连接到手机4626端口,进行socket通信。PC端代码如下:

 

[htML] 
DWORD WINAPI usbThreaDFunc(LpvOID threadNum) 
{  
    int length;   
    CString temp;  
    if(!inITAdb())//adb init 
    {  
        MessageBox(0, L"初始化手机出错!", L"提示", MB_OK);  
        return 0;  
    }  
    if(!InItClientSock())//socket init 
    {  
        MessageBox(0, L"初始化IP地址出错!", L"提示", MB_OK);  
        return 0;  
    }  
    if(!USBConnectSock((HWND)threadNum))//connect socket 
    {  
        MessageBox(0, L"连接IP地址出错!", L"提示", MB_OK);  
        return 0;  
    }  
    //等待连接的时候,连接可能被取消。 
    if(clientThreadRun) 
    {  
    }  
    else 
    {  
        MessageBox(0, L"用户取消!", L"提示", MB_OK);  
        return 0;  
    }  
    SetDlgItemText( (HWND)threadNum, IDC_SOUNDFILE, TEXT("& USB Disconnect") );  
    EnableWindow( GetDlgItem( (HWND)threadNum, IDC_RECORD ), TRUE );  
    EnableWindow( GetDlgItem( (HWND)threadNum, IDC_BUTTON_wifi ), FALSE );    
    while(clientThreadRun) 
    {  
        if( (length = recv(clientSock,(char*)recv_message_client,sizeof(recv_message_client),0))> 0) 
        {  
            memset(recv_message_client, 0, sizeof(recv_message_client));  
            LOGPRintf(recv_message_client);  
        }         
    }  
    return 0;  
}  

DWORD WINAPI usBThreadFunc(LPVOID threadNum)
{
 int length;  
 CString temp;
 if(!initAdb())//adb init
 {
  messageBox(0, L"初始化手机出错!", L"提示", MB_OK);
  return 0;
 }
 if(!InItClientSock())//socket init
 {
  MessageBox(0, L"初始化IP地址出错!", L"提示", MB_OK);
  return 0;
 }
 if(!USBConnectSock((HWND)threadNum))//connect socket
 {
  MessageBox(0, L"连接IP地址出错!", L"提示", MB_OK);
  return 0;
 }
 //等待连接的时候,连接可能被取消。
 if(clientThreadRun)
 {
 }
 else
 {
  MessageBox(0, L"用户取消!", L"提示", MB_OK);
  return 0;
 }
 SetDlgItemText( (HWND)threadNum, IDC_SOUNDFILE, TEXT("& USB Disconnect") );
 EnableWindow( GetDlgItem( (HWND)threadNum, IDC_RECORD ), TRUE );
 EnableWindow( GetDlgItem( (HWND)threadNum, IDC_BUTTON_WIFI ), FALSE );  
 while(clientThreadRun)
 {
  if( (length = recv(clientSock,(char*)recv_message_client,sizeof(recv_message_client),0))> 0)
  {
   memset(recv_message_client, 0, sizeof(recv_message_client));
   LogPrintf(recv_message_client);
  }   
 }
 return 0;
}

这里说道最重要的是捕获声音,下面的代码启动了一个线程来处理捕获到的声音:


[html] 
DWORD WINAPI captureThreadFunc(LPVOID hDlg) 
{  
    DWORD dwResult;  
    while(g_brecording)  
    {   
        dwResult = MsgWaitForMultipleObjects( 1, & g_hNotificationEvent, FALSE, INFINITE, QS_ALLEVENTS );  
        switch( dwResult ) 
        {  
        case statUS_WAIT_0://case WAIT_OBJECT_0 + 0: 
 
            RecordCapturedData();  
            break;  
        }  
    }  
    return 0;  
}  

DWORD WINAPI captureThreadFunc(LPVOID hDlg)
{
 DWORD dwResult;
 while(g_bRecording)
 {
  dwResult = MsgWaitForMultipleObjects( 1, & g_hNotificationEvent, FALSE, INFINITE, QS_ALLEVENTS );
  switch( dwResult )
  {
  case STATUS_WAIT_0://case WAIT_OBJECT_0 + 0:

   RecordCapturedData();
   break;
  }
 }
 return 0;
}

在创建捕获声音的设备的时候,会创建一个事件,这个事件就是捕获到一定长度的声音之后(比如2K大小的声音),会发出一个通知,告诉你去处理。上面的线程,就是一直待等待这个事件,然后再去处理捕获到的声音,把声音发送给socket,交给手机处理,代码:


[html] 
HRESULT RecordCapturedData()  
{  
    HRESULT hr;  
    VOID*   pbCaptureData    = NULL;  
    DWORD   dwCaptureLength;  
    VOID*   pbCaptureData2   = NULL;  
    DWORD   dwCaptureLength2;  
    DWORD   dwReadPos;  
    DWORD   dwCapturePos;  
    LONG lLockSize;  
 
    if( NULL == g_pDSBCapture ) 
        return S_FALSE;  
 
    if( FAILED( hr = g_pDSBCapture-> GetcurrentPosition( & dwCapturePos, & dwReadPos ) ) ) 
        return DXTRACE_ERR_MSGBOX( TEXT("GetCurrentPosition"), hr );  
 
    lLockSize = dwReadPos - g_dwNextCaptureOffset;  
    if( lLockSize 0 ) 
        lLockSize += g_dwCaptureBufferSize;  
 
    // Block align lock size so that we are always write on a boundary 
    lLockSize -= (lLockSize % g_dwNotifySize);  
 
    if( lLockSize == 0 ) 
        return S_FALSE;  
 
    // Lock the capture buffer down 
    if( FAILED( hr = g_pDSBCapture-> Lock( g_dwNextCaptureOffset, lLockSize,  
                                          & pbCaptureData, & dwCaptureLength,  
                                          & pbCaptureData2, & dwCaptureLength2, 0L ) ) ) 
        return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr );  
 
     
    // Write the data to socket发送给手机 
    socketSend(pbCaptureData,dwCaptureLength);  
    // Move the capture offset along 
    g_dwNextCaptureOffset += dwCaptureLength;   
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer 
 
    if( pbCaptureData2 != NULL ) 
    {  
        // Write the data to socket发送给手机 
        socketSend(pbCaptureData2,dwCaptureLength2);  
 
        // Move the capture offset along 
        g_dwNextCaptureOffset += dwCaptureLength2;   
        g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer 
    }  
 
    // Unlock the capture buffer 
    g_pDSBCapture-> Unlock( pbCaptureData,  dwCaptureLength,  
                           pbCaptureData2, dwCaptureLength2 );  
    return S_OK;  
}  

HRESULT RecordCapturedData()
{
    HRESULT hr;
    VOID*   pbCaptureData    = NULL;
    DWORD   dwCaptureLength;
    VOID*   pbCaptureData2   = NULL;
    DWORD   dwCaptureLength2;
    DWORD   dwReadPos;
    DWORD   dwCapturePos;
    LONG lLockSize;

    if( NULL == g_pDSBCapture )
        return S_FALSE;

    if( FAILED( hr = g_pDSBCapture-> GetCurrentPosition( & dwCapturePos, & dwReadPos ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("GetCurrentPosition"), hr );

    lLockSize = dwReadPos - g_dwNextCaptureOffset;
    if( lLockSize 0 )
        lLockSize += g_dwCaptureBufferSize;

    // Block align lock size so that we are always write on a boundary
    lLockSize -= (lLockSize % g_dwNotifySize);

    if( lLockSize == 0 )
        return S_FALSE;

    // Lock the capture buffer down
    if( FAILED( hr = g_pDSBCapture-> Lock( g_dwNextCaptureOffset, lLockSize,
                                          & pbCaptureData, & dwCaptureLength,
                                          & pbCaptureData2, & dwCaptureLength2, 0L ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr );

 
    // Write the data to socket发送给手机
 socketSend(pbCaptureData,dwCaptureLength);
    // Move the capture offset along
    g_dwNextCaptureOffset += dwCaptureLength;
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer

    if( pbCaptureData2 != NULL )
    {
        // Write the data to socket发送给手机
   socketSend(pbCaptureData2,dwCaptureLength2);

        // Move the capture offset along
        g_dwNextCaptureOffset += dwCaptureLength2;
        g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer
    }

    // Unlock the capture buffer
    g_pDSBCapture-> Unlock( pbCaptureData,  dwCaptureLength,
                           pbCaptureData2, dwCaptureLength2 );
    return S_OK;
}

通过socket发送数据的代码很简单,没有任何处理捕获到的声音数据,就发送给手机了

[html]
VOID socketSend(VOID* send_message, int length) 
{  
    if(clientSockConnect==0) 
    {         
        int send_len = length;  
        char * buf = (char*)send_message;  
 
        while(send_len> 0) 
        {         
            int rc = send(clientSock,buf,send_len, 0); //MSG_OOB 
            if (rc 1)//if (rc == SOCKET_ERROR || rc == 0) 
            {  
                break;  
            }     
            send_len -= rc;  
            buf += rc;  
        }  
        buf = NULL;  
    }  
}  

VOID socketSend(VOID* send_message, int length)
{
 if(clientSockConnect==0)
 {   
  int send_len = length;
  char * buf = (char*)send_message;

  while(send_len> 0)
  {   
   int rc = send(clientSock,buf,send_len, 0); //MSG_OOB
   if (rc 1)//if (rc == SOCKET_ERROR || rc == 0)
   {
    break;
   }  
   send_len -= rc;
   buf += rc;
  }
  buf = NULL;
 }
}
手机端的代码如下,注意手机上audioTrack的设置:44100,AudioFormat.CHANNEL_configURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT。在启动电脑捕获声音的时候也要同样的设置,否则播放的声音是杂音:


[html] 
public class TcpConnect extends Thread {  
    private ServerSocket mServerSocket;  
    private Socket mClient;  
    private Handler mHandler;  
    private boolean running = false;  
    private boolean palying = false;  
 
    private int audioplayBufSize;  
    private AudioTrack audioTrack;  
    private static final int frequency = 44100;  
    private static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;  
    private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;  
 
    private ArrayListbyte[]> inBuf = new ArrayListbyte[]> ();  
 
    public TcpConnect(Handler handler) {  
        mHandler = handler;  
 
        audioPlayBufSize = AudioTrack.getMinBufferSize(frequency, 
                channelConfiguration, audioEncoding);  
        audioTrack = new AudioTrack( 
                AudioManager.STREAM_MUSIC,// .STREAM_RING,//.STREAM_MUSIC, 
                frequency, channelConfiguration, audioEncoding, 
                audioPlayBufSize, AudioTrack.MODE_STREAM);  
        audioTrack.setStereoVolume(1.0f, 1.0f);  
        Log.d("playPCAudio", "audioPlayBufSize: " + audioPlayBufSize);  
 
        palying = false;  
        inBuf.clear();  
    }  
 
    public void run() {  
        try {  
            mServerSocket = new ServerSocket(4883);  
 
            System.out.println("TcpConnect" + "开始监听");  
            mClient = mServerSocket.accept();  
            System.out.println("TcpConnect" + "检测到有连接");  
            InputStream is = mClient.getInputStream();  
 
            running = true;  
            int readLen = 0;  
            byte[] readBuf = new byte[audioPlayBufSize];  
 
            System.out.println("TcpConnect" + "接收");  
            playThread palyt = new playThread();  
            palyt.setPriority(Thread.MAX_PRIORITY);  
            palyt.start();  
 
            while (running) {  
                if ((readLen = is.read(readBuf, 0, audioPlayBufSize)) > 0) {  
                    byte[] tmpBuf = new byte[readLen];  
                    System.arraycopy(readBuf, 0, tmpBuf, 0, readLen);  
                    synchronized (inBuf) {  
                        inBuf.add(tmpBuf);  
                    }  
                }  
            }  
        } catch (Exception e) {  
            System.out.println("TcpConnect TCP error:" + e.getMessage());  
        }  
        System.out.println("TcpConnect over");  
    }  
 
    class playThread extends Thread {  
 
        public playThread() {  
        }  
        public void run() {  
            audioTrack.play();  
            palying = true;  
 
            while (running) {  
                ArrayListbyte[]> buf = new ArrayListbyte[]> ();  
                buf.clear();  
                synchronized (inBuf) {  
                    if (inBuf.size() == 0) 
                        continue;  
                    buf = (ArrayListbyte[]> ) inBuf.clone();  
                    inBuf.clear();  
                }  
                for (int i = 0; i buf.size(); i++) {  
                    byte[] tmpBuf = buf.get(i);  
                    audioTrack.write(tmpBuf, 0, tmpBuf.length);  
                }  
            }  
            if (palying) {  
                audioTrack.stop();  
                audioTrack.release();  
                palying = false;  
            }  
        }  
    }  
}  

在pc上使用adb命令:adb forward tcp:4626 tcp:4883,在PC上建立4626端口通信数据将被重定向到手机端server的4883端口;然后初始化socket,连接到手机4626端口,进行socket通信。PC端代码如下:

 

[html] 
DWORD WINAPI usbThreadFunc(LPVOID threadNum) 
{  
    int length;   
    CString temp;  
    if(!initAdb())//adb init 
    {  
        MessageBox(0, L"初始化手机出错!", L"提示", MB_OK);  
        return 0;  
    }  
    if(!InItClientSock())//socket init 
    {  
        MessageBox(0, L"初始化IP地址出错!", L"提示", MB_OK);  
        return 0;  
    }  
    if(!USBConnectSock((HWND)threadNum))//connect socket 
    {  
        MessageBox(0, L"连接IP地址出错!", L"提示", MB_OK);  
        return 0;  
    }  
    //等待连接的时候,连接可能被取消。 
    if(clientThreadRun) 
    {  
    }  
    else 
    {  
        MessageBox(0, L"用户取消!", L"提示", MB_OK);  
        return 0;  
    }  
    SetDlgItemText( (HWND)threadNum, IDC_SOUNDFILE, TEXT("& USB Disconnect") );  
    EnableWindow( GetDlgItem( (HWND)threadNum, IDC_RECORD ), TRUE );  
    EnableWindow( GetDlgItem( (HWND)threadNum, IDC_BUTTON_WIFI ), FALSE );    
    while(clientThreadRun) 
    {  
        if( (length = recv(clientSock,(char*)recv_message_client,sizeof(recv_message_client),0))> 0) 
        {  
            memset(recv_message_client, 0, sizeof(recv_message_client));  
            LogPrintf(recv_message_client);  
        }         
    }  
    return 0;  
}  

DWORD WINAPI usbThreadFunc(LPVOID threadNum)
{
 int length;  
 CString temp;
 if(!initAdb())//adb init
 {
  MessageBox(0, L"初始化手机出错!", L"提示", MB_OK);
  return 0;
 }
 if(!InItClientSock())//socket init
 {
  MessageBox(0, L"初始化IP地址出错!", L"提示", MB_OK);
  return 0;
 }
 if(!USBConnectSock((HWND)threadNum))//connect socket
 {
  MessageBox(0, L"连接IP地址出错!", L"提示", MB_OK);
  return 0;
 }
 //等待连接的时候,连接可能被取消。
 if(clientThreadRun)
 {
 }
 else
 {
  MessageBox(0, L"用户取消!", L"提示", MB_OK);
  return 0;
 }
 SetDlgItemText( (HWND)threadNum, IDC_SOUNDFILE, TEXT("& USB Disconnect") );
 EnableWindow( GetDlgItem( (HWND)threadNum, IDC_RECORD ), TRUE );
 EnableWindow( GetDlgItem( (HWND)threadNum, IDC_BUTTON_WIFI ), FALSE );  
 while(clientThreadRun)
 {
  if( (length = recv(clientSock,(char*)recv_message_client,sizeof(recv_message_client),0))> 0)
  {
   memset(recv_message_client, 0, sizeof(recv_message_client));
   LogPrintf(recv_message_client);
  }   
 }
 return 0;
}

这里说道最重要的是捕获声音,下面的代码启动了一个线程来处理捕获到的声音:


[html] 
DWORD WINAPI captureThreadFunc(LPVOID hDlg) 
{  
    DWORD dwResult;  
    while(g_bRecording)  
    {   
        dwResult = MsgWaitForMultipleObjects( 1, & g_hNotificationEvent, FALSE, INFINITE, QS_ALLEVENTS );  
        switch( dwResult ) 
        {  
        case STATUS_WAIT_0://case WAIT_OBJECT_0 + 0: 
 
            RecordCapturedData();  
            break;  
        }  
    }  
    return 0;  
}  

DWORD WINAPI captureThreadFunc(LPVOID hDlg)
{
 DWORD dwResult;
 while(g_bRecording)
 {
  dwResult = MsgWaitForMultipleObjects( 1, & g_hNotificationEvent, FALSE, INFINITE, QS_ALLEVENTS );
  switch( dwResult )
  {
  case STATUS_WAIT_0://case WAIT_OBJECT_0 + 0:

   RecordCapturedData();
   break;
  }
 }
 return 0;
}

在创建捕获声音的设备的时候,会创建一个事件,这个事件就是捕获到一定长度的声音之后(比如2K大小的声音),会发出一个通知,告诉你去处理。上面的线程,就是一直待等待这个事件,然后再去处理捕获到的声音,把声音发送给socket,交给手机处理,代码:


[html] 
HRESULT RecordCapturedData()  
{  
    HRESULT hr;  
    VOID*   pbCaptureData    = NULL;  
    DWORD   dwCaptureLength;  
    VOID*   pbCaptureData2   = NULL;  
    DWORD   dwCaptureLength2;  
    DWORD   dwReadPos;  
    DWORD   dwCapturePos;  
    LONG lLockSize;  
 
    if( NULL == g_pDSBCapture ) 
        return S_FALSE;  
 
    if( FAILED( hr = g_pDSBCapture-> GetCurrentPosition( & dwCapturePos, & dwReadPos ) ) ) 
        return DXTRACE_ERR_MSGBOX( TEXT("GetCurrentPosition"), hr );  
 
    lLockSize = dwReadPos - g_dwNextCaptureOffset;  
    if( lLockSize 0 ) 
        lLockSize += g_dwCaptureBufferSize;  
 
    // Block align lock size so that we are always write on a boundary 
    lLockSize -= (lLockSize % g_dwNotifySize);  
 
    if( lLockSize == 0 ) 
        return S_FALSE;  
 
    // Lock the capture buffer down 
    if( FAILED( hr = g_pDSBCapture-> Lock( g_dwNextCaptureOffset, lLockSize,  
                                          & pbCaptureData, & dwCaptureLength,  
                                          & pbCaptureData2, & dwCaptureLength2, 0L ) ) ) 
        return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr );  
 
     
    // Write the data to socket发送给手机 
    socketSend(pbCaptureData,dwCaptureLength);  
    // Move the capture offset along 
    g_dwNextCaptureOffset += dwCaptureLength;   
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer 
 
    if( pbCaptureData2 != NULL ) 
    {  
        // Write the data to socket发送给手机 
        socketSend(pbCaptureData2,dwCaptureLength2);  
 
        // Move the capture offset along 
        g_dwNextCaptureOffset += dwCaptureLength2;   
        g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer 
    }  
 
    // Unlock the capture buffer 
    g_pDSBCapture-> Unlock( pbCaptureData,  dwCaptureLength,  
                           pbCaptureData2, dwCaptureLength2 );  
    return S_OK;  
}  

HRESULT RecordCapturedData()
{
    HRESULT hr;
    VOID*   pbCaptureData    = NULL;
    DWORD   dwCaptureLength;
    VOID*   pbCaptureData2   = NULL;
    DWORD   dwCaptureLength2;
    DWORD   dwReadPos;
    DWORD   dwCapturePos;
    LONG lLockSize;

    if( NULL == g_pDSBCapture )
        return S_FALSE;

    if( FAILED( hr = g_pDSBCapture-> GetCurrentPosition( & dwCapturePos, & dwReadPos ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("GetCurrentPosition"), hr );

    lLockSize = dwReadPos - g_dwNextCaptureOffset;
    if( lLockSize 0 )
        lLockSize += g_dwCaptureBufferSize;

    // Block align lock size so that we are always write on a boundary
    lLockSize -= (lLockSize % g_dwNotifySize);

    if( lLockSize == 0 )
        return S_FALSE;

    // Lock the capture buffer down
    if( FAILED( hr = g_pDSBCapture-> Lock( g_dwNextCaptureOffset, lLockSize,
                                          & pbCaptureData, & dwCaptureLength,
                                          & pbCaptureData2, & dwCaptureLength2, 0L ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr );

 
    // Write the data to socket发送给手机
 socketSend(pbCaptureData,dwCaptureLength);
    // Move the capture offset along
    g_dwNextCaptureOffset += dwCaptureLength;
    g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer

    if( pbCaptureData2 != NULL )
    {
        // Write the data to socket发送给手机
   socketSend(pbCaptureData2,dwCaptureLength2);

        // Move the capture offset along
        g_dwNextCaptureOffset += dwCaptureLength2;
        g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer
    }

    // Unlock the capture buffer
    g_pDSBCapture-> Unlock( pbCaptureData,  dwCaptureLength,
                           pbCaptureData2, dwCaptureLength2 );
    return S_OK;
}

通过socket发送数据的代码很简单,没有任何处理捕获到的声音数据,就发送给手机了

[html]
VOID socketSend(VOID* send_message, int length) 
{  
    if(clientSockConnect==0) 
    {         
        int send_len = length;  
        char * buf = (char*)send_message;  
 
        while(send_len> 0) 
        {         
            int rc = send(clientSock,buf,send_len, 0); //MSG_OOB 
            if (rc 1)//if (rc == SOCKET_ERROR || rc == 0) 
            {  
                break;  
            }     
            send_len -= rc;  
            buf += rc;  
        }  
        buf = NULL;  
    }  
}  

VOID socketSend(VOID* send_message, int length)
{
 if(clientSockConnect==0)
 {   
  int send_len = length;
  char * buf = (char*)send_message;

  while(send_len> 0)
  {   
   int rc = send(clientSock,buf,send_len, 0); //MSG_OOB
   if (rc 1)//if (rc == SOCKET_ERROR || rc == 0)
   {
    break;
   }  
   send_len -= rc;
   buf += rc;
  }
  buf = NULL;
 }
}
手机端的代码如下,注意手机上audioTrack的设置:44100,AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT。在启动电脑捕获声音的时候也要同样的设置,否则播放的声音是杂音:


[html] 
public class TcpConnect extends Thread {  
    private ServerSocket mServerSocket;  
    private Socket mClient;  
    private Handler mHandler;  
    private boolean running = false;  
    private boolean palying = false;  
 
    private int audioPlayBufSize;  
    private AudioTrack audioTrack;  
    private static final int frequency = 44100;  
    private static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;  
    private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;  
 
    private ArrayListbyte[]> inBuf = new ArrayListbyte[]> ();  
 
    public TcpConnect(Handler handler) {  
        mHandler = handler;  
 
        audioPlayBufSize = AudioTrack.getMinBufferSize(frequency, 
                channelConfiguration, audioEncoding);  
        audioTrack = new AudioTrack( 
                AudioManager.STREAM_MUSIC,// .STREAM_RING,//.STREAM_MUSIC, 
                frequency, channelConfiguration, audioEncoding, 
                audioPlayBufSize, AudioTrack.MODE_STREAM);  
        audioTrack.setStereoVolume(1.0f, 1.0f);  
        Log.d("playPCAudio", "audioPlayBufSize: " + audioPlayBufSize);  
 
        palying = false;  
        inBuf.clear();  
    }  
 
    public void run() {  
        try {  
            mServerSocket = new ServerSocket(4883);  
 
            System.out.println("TcpConnect" + "开始监听");  
            mClient = mServerSocket.accept();  
            System.out.println("TcpConnect" + "检测到有连接");  
            InputStream is = mClient.getInputStream();  
 
            running = true;  
            int readLen = 0;  
            byte[] readBuf = new byte[audioPlayBufSize];  
 
            System.out.println("TcpConnect" + "接收");  
            playThread palyt = new playThread();  
            palyt.setPriority(Thread.MAX_PRIORITY);  
            palyt.start();  
 
            while (running) {  
                if ((readLen = is.read(readBuf, 0, audioPlayBufSize)) > 0) {  
                    byte[] tmpBuf = new byte[readLen];  
                    System.arraycopy(readBuf, 0, tmpBuf, 0, readLen);  
                    synchronized (inBuf) {  
                        inBuf.add(tmpBuf);  
                    }  
                }  
            }  
        } catch (Exception e) {  
            System.out.println("TcpConnect TCP error:" + e.getMessage());  
        }  
        System.out.println("TcpConnect over");  
    }  
 
    class playThread extends Thread {  
 
        public playThread() {  
        }  
        public void run() {  
            audioTrack.play();  
            palying = true;  
 
            while (running) {  
                ArrayListbyte[]> buf = new ArrayListbyte[]> ();  
                buf.clear();  
                synchronized (inBuf) {  
                    if (inBuf.size() == 0) 
                        continue;  
                    buf = (ArrayListbyte[]> ) inBuf.clone();  
                    inBuf.clear();  
                }  
                for (int i = 0; i buf.size(); i++) {  
                    byte[] tmpBuf = buf.get(i);  
                    audioTrack.write(tmpBuf, 0, tmpBuf.length);  
                }  
            }  
            if (palying) {  
                audioTrack.stop();  
                audioTrack.release();  
                palying = false;  
            }  
        }  
    }  
}  

觉得可用,就经常来吧! 欢迎评论哦! html5教程,巧夺天工,精雕玉琢。小宝典献丑了!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

APIArrayClassdivHTMLpost-format-gallery

若转载请注明出处: 捕获电脑的声音放到手机播放
本文地址: https://pptw.com/jishu/586486.html
HTML 5 Web SQL Database初探 你不知道的5个HTML5 API

游客 回复需填写必要信息