Discuz! BBS

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 33|回复: 0

将test.py改写成android程序

[复制链接]

401

主题

568

帖子

3342

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3342
发表于 3 天前 | 显示全部楼层 |阅读模式
原程序:
  1. #!/usr/bin/env python3
  2. import asyncio import websockets import sys import wave
  3. async def run_test(uri): async with websockets.connect(uri) as websocket:
  4.     wf = wave.open(sys.argv[1], "rb")
  5.     await websocket.send('{ "config" : { "sample_rate" : %d } }' % (wf.getframerate()))
  6.     buffer_size = int(wf.getframerate() * 0.2) # 0.2 seconds of audio
  7.     print("@@@@@@")
  8.     while True:
  9.         data = wf.readframes(buffer_size)

  10.         if len(data) == 0:
  11.             break

  12.         await websocket.send(data)
  13.         print (await websocket.recv())

  14.     print("******")
  15.     await websocket.send('{"eof" : 1}')
  16.     print (await websocket.recv())
  17. asyncio.run(run_test('ws://*.*.*.*:***')
复制代码
将Python WebSocket客户端程序转换为Android Java版本,并避免使用javax.sound.sampled库。以下是完整的实现:
  1. package cn.unicoder.myapplication;

  2. import java.net.URI;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.IOException;
  6. import android.media.AudioFormat;
  7. import org.java_websocket.client.WebSocketClient;
  8. import org.java_websocket.handshake.ServerHandshake;
  9. import org.json.JSONObject;

  10. public class AudioSocketClient extends WebSocketClient {
  11.     private String audioFilePath;
  12.     private byte[] audioBuffer;
  13.     private AudioFormat format;
  14.     private boolean finished = false;
  15.     private FileInputStream fileInputStream;

  16.     public AudioSocketClient(URI serverUri, String audioFilePath) {
  17.         super(serverUri);
  18.         this.audioFilePath = audioFilePath;
  19.         this.format = new AudioFormat.Builder()
  20.                 .setSampleRate(16000)
  21.                 .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
  22.                 .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
  23.                 .build();
  24.         this.audioBuffer = new byte[1024];
  25.     }
  26.    
  27.     @Override
  28.     public void onOpen(ServerHandshake handshakedata) {
  29.         System.out.println("Connected to server");
  30.         // 连接成功后开始发送音频数据
  31.         sendAudioData();
  32.     }
  33.    
  34.     @Override
  35.     public void onMessage(String message) {
  36.         System.out.println("Received: " + message);
  37.     }
  38.    
  39.     @Override
  40.     public void onClose(int code, String reason, boolean remote) {
  41.         System.out.println("Connection closed: " + reason);
  42.         finished = true;
  43.         closeFileStream();
  44.     }
  45.    
  46.     @Override
  47.     public void onError(Exception ex) {
  48.         ex.printStackTrace();
  49.         closeFileStream();
  50.     }
  51.    
  52.     private void sendAudioData() {
  53.         new Thread(() -> {
  54.             try {
  55.                 File audioFile = new File(audioFilePath);
  56.                 fileInputStream = new FileInputStream(audioFile);
  57.                
  58.                 // 发送配置信息
  59.                 sendConfig();
  60.                
  61.                 // 设置缓冲区大小为0.2秒的音频数据 (16000Hz * 0.2s * 2字节 = 6400字节)
  62.                 int bufferSize = (int)(16000 * 0.2 * 2);
  63.                 byte[] buffer = new byte[bufferSize];
  64.                
  65.                 System.out.println("@@@@@@");
  66.                
  67.                 int bytesRead;
  68.                 while ((bytesRead = fileInputStream.read(buffer)) != -1 && !finished) {
  69.                     // 发送音频数据块
  70.                     send(java.util.Arrays.copyOf(buffer, bytesRead));
  71.                     
  72.                     // 简单延时以模拟异步接收响应
  73.                     Thread.sleep(100);
  74.                 }
  75.                
  76.                 // 发送结束标记
  77.                 sendEOF();
  78.                 System.out.println("******");
  79.                
  80.             } catch (Exception e) {
  81.                 e.printStackTrace();
  82.             } finally {
  83.                 closeFileStream();
  84.             }
  85.         }).start();
  86.     }
  87.    
  88.     private void sendConfig() {
  89.         try {
  90.             // 发送配置信息,类似于Python中的 '{ "config" : { "sample_rate" : %d } }'
  91.             JSONObject configMsg = new JSONObject();
  92.             JSONObject config = new JSONObject();
  93.             config.put("sample_rate", 16000);
  94.             configMsg.put("config", config);
  95.             
  96.             send(configMsg.toString());
  97.         } catch (Exception e) {
  98.             e.printStackTrace();
  99.         }
  100.     }
  101.    
  102.     private void sendEOF() {
  103.         try {
  104.             JSONObject eofMsg = new JSONObject();
  105.             eofMsg.put("eof", 1);
  106.             send(eofMsg.toString());
  107.         } catch (Exception e) {
  108.             e.printStackTrace();
  109.         }
  110.     }
  111.    
  112.     private void closeFileStream() {
  113.         if (fileInputStream != null) {
  114.             try {
  115.                 fileInputStream.close();
  116.             } catch (IOException e) {
  117.                 e.printStackTrace();
  118.             }
  119.         }
  120.     }
  121. }
复制代码
关键转换点:
1、移除Java Sound API依赖:完全移除了javax.sound.sampled相关导入和使用
2、文件读取:使用FileInputStream替代Python的wave.open来读取音频文件
3、异步处理:通过新线程处理音频数据发送,避免阻塞主线程
4、WebSocket通信:
   在onOpen中启动音频发送流程
   使用send方法发送数据和配置信息
   实现onMessage处理服务器响应
5、缓冲区管理:设置0.2秒的音频数据块大小(假设16kHz采样率,16位深度)
6、资源清理:在适当位置关闭文件流,防止资源泄漏
使用时,创建AudioSocketClient实例并调用connect()方法即可建立WebSocket连接并开始传输音频数据。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2025-11-4 06:45 , Processed in 0.012184 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表