捕获电脑的声音放到手机播放
来源:互联网 发布:ios 省市区json数据 编辑:程序博客网 时间:2024/06/11 23:41
最近笔记本的音响坏了,郁闷啊、纠结中,有一个想法:捕获电脑的声音,这个声音可以是movie的声音、music的声音、或者系统的声音,只要是经过声卡播放的声音,都可以捕获。然后通过usb发送到手机上播放,也可以通过wifi发送到手机播放。
看看怎么做,可以使用微软发布的DirectX SDK,我使用的是DirectX 10 SDK,很多地方可以下载到这个sdk, 大小500M左右。在sdk的目录DirectX 10 SDK\Samples\C++\DirectSound下,有一个例子CaptureSound,CaptureSound是用来捕获声音的,它一面捕获声音,一面写进一个wav的文件里。修改这个例子,把捕获的声音立即发送给手机,可以通过usb发送、或者wifi。
首先设置pc的录音通道,在电脑的托盘上,双击小喇叭,菜单“选项”->“属性”,选择“录音”,只勾选“立体声混音”。看一下效果:
转载,请写明出处:http://blog.csdn.net/menghnhhuan/article/details/8281747
usb通信时这样的:
在pc上使用adb命令:adb forward tcp:4626 tcp:4883,在PC上建立4626端口通信数据将被重定向到手机端server的4883端口;然后初始化socket,连接到手机4626端口,进行socket通信。PC端代码如下:
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 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,交给手机处理,代码:
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发送数据的代码很简单,没有任何处理捕获到的声音数据,就发送给手机了
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_OOBif (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。在启动电脑捕获声音的时候也要同样的设置,否则播放的声音是杂音:
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 ArrayList<byte[]> inBuf = new ArrayList<byte[]>();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) {ArrayList<byte[]> buf = new ArrayList<byte[]>();buf.clear();synchronized (inBuf) {if (inBuf.size() == 0)continue;buf = (ArrayList<byte[]>) 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;}}}}
我的博客:http://blog.csdn.net/menghnhhuan
PC和手机的代码下载地址:
http://download.csdn.net/detail/menghnhhuan/4873008
大家在捕获声音的时候,可能会出现杂音,需要调试,请留言。
有需要的同学在这里下载:http://pan.baidu.com/s/17W5Tt
已经上传到百度网盘,里面有使用说明。CSDN的下载链接需要积分,无法修改。
- 捕获电脑的声音放到手机播放
- 同步听 一款捕获电脑声音到手机播放
- 在电脑中播放声音的方法
- 手机播放声音和震动
- 在 Motorola 手机中,播放声音的注意点
- 手机游戏中声音的播放及处理
- 电脑里的所有播放器只能播放声音没有画面
- 把电脑是那个的图片通过命令放到手机或模拟器上
- 播放器的声音
- 播放声音的问题
- Nokia手机来电时,手机游戏中声音重新播放处理的bug
- android dlna 播放手机和电脑上的视频
- 兼容手机和电脑的视频播放器代码
- nokia s40 手机 循环播放声音
- 电脑播放视频切断重新播放声音变大
- 解决电脑杀毒的后遗症:有声音但不能播放音乐
- 解决电脑杀毒的后遗症:有声音但不能播放音乐
- Windows 10 电脑在播放声音后突然增大的解决办法
- Java程序员都应该知道的福利
- 关于人生
- 360再遇“报告门” 互联网隐私安全持续升温
- [Shell] Linux与Windows之间传输文件或文件夹
- asp.net mvc 缓存
- 捕获电脑的声音放到手机播放
- Android之用PopupWindow实现弹出菜单
- 黑马程序员_IO小结
- 加载外部XML文档
- 年月日的数据实现方式
- jquery ui dialog控件与 html5 兼容性问题
- OpenCPN介绍及编译
- 内网调试使用微软符号
- 【Android Trick 2】HTTPS请求忽略证书