手机之间传输文件:通过WiFi在Android手机之间流式传输语音

关于手机之间传输文件的问题,在livestream the voice中经常遇到, 我试图从麦克风流音频从 1 Android 到另一个通过 WiFi。看了一些例子后,我做了 2 个应用程序与每个单一的活动,1 捕获和发送音频和其他接收。

我试图从麦克风流音频从 1 Android 到另一个通过 WiFi。看了一些例子后,我做了 2 个应用程序与每个单一的活动,1 捕获和发送音频和其他接收。

我已经使用 Audiorecord 和 Audiotrack 类捕获和播放。但是,我只是听到一些噼啪声(虽然我恢复了一些变化,但现在已经停止)

要发送语音的活动。

public class VoiceSenderActivity extends Activity {
private EditText target;
private TextView streamingLabel;
private Button startButton,stopButton;
public byte[] buffer;
public static DatagramSocket socket;
private int port=50005;         //which port??
AudioRecord recorder;
//Audio Configuration. 
private int sampleRate = 8000;      //How much will be ideal?
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;    
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;       
private boolean status = true;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    target = (EditText) findViewById (R.id.target_IP);
    streamingLabel = (TextView) findViewById(R.id.streaming_label);
    startButton = (Button) findViewById (R.id.start_on);
    stopButton = (Button) findViewById (R.id.stop_on);
    streamingLabel.setText("Press Start! to begin");
    startButton.setOnClickListener (startListener);
    stopButton.setOnClickListener (stopListener);
}
private final OnClickListener stopListener = new OnClickListener() {
    @Override
    public void onClick(View arg0) {
                status = false;
                recorder.release();
                Log.d("VS","Recorder released");
    }
};
private final OnClickListener startListener = new OnClickListener() {
    @Override
    public void onClick(View arg0) {
                status = true;
                startStreaming();           
    }
};
public void startStreaming() {
    Thread streamThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
                DatagramSocket socket = new DatagramSocket();
                Log.d("VS", "Socket Created");
                byte[] buffer = new byte[minBufSize];
                Log.d("VS","Buffer created of size " + minBufSize);
                DatagramPacket packet;
                final InetAddress destination = InetAddress.getByName(target.getText().toString());
                Log.d("VS", "Address retrieved");
                recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize);
                Log.d("VS", "Recorder initialized");
                recorder.startRecording();
                while(status == true) {
                    //reading data from MIC into buffer
                    minBufSize = recorder.read(buffer, 0, buffer.length);
                    //putting buffer in the packet
                    packet = new DatagramPacket (buffer,buffer.length,destination,port);
                    socket.send(packet);
                }
            } catch(UnknownHostException e) {
                Log.e("VS", "UnknownHostException");
            } catch (IOException e) {
                Log.e("VS", "IOException");
            } 
        }
    });
    streamThread.start();
 }
 }

要接收语音的活动

public class VoiceReceiverActivity extends Activity {
private Button receiveButton,stopButton;
public static DatagramSocket socket;
private AudioTrack speaker;
//Audio Configuration. 
private int sampleRate = 8000;      //How much will be ideal?
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;    
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;       
private boolean status = true;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    receiveButton = (Button) findViewById (R.id.receive_on);
    stopButton = (Button) findViewById (R.id.stop_on);
    findViewById(R.id.receive_label);
    receiveButton.setOnClickListener(receiveListener);
    stopButton.setOnClickListener(stopListener);
}
private final OnClickListener stopListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
        status = false;
        speaker.release();
        Log.d("VR","Speaker released");
    }
};
private final OnClickListener receiveListener = new OnClickListener() {
    @Override
    public void onClick(View arg0) {
        status = true;
        startReceiving();
    }
};
public void startReceiving() {
    Thread receiveThread = new Thread (new Runnable() {
        @Override
        public void run() {
            try {
                DatagramSocket socket = new DatagramSocket(50005);
                Log.d("VR", "Socket Created");
                byte[] buffer = new byte[256];
                //minimum buffer size. need to be careful. might cause problems. try setting manually if any problems faced
                int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
                speaker = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,channelConfig,audioFormat,minBufSize,AudioTrack.MODE_STREAM);
                speaker.play();
                while(status == true) {
                    try {
                        DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
                        socket.receive(packet);
                        Log.d("VR", "Packet Received");
                        //reading content from packet
                        buffer=packet.getData();
                        Log.d("VR", "Packet data read into buffer");
                        //sending data to the Audiotrack obj i.e. speaker
                        speaker.write(buffer, 0, minBufSize);
                        Log.d("VR", "Writing buffer content to speaker");
                    } catch(IOException e) {
                        Log.e("VR","IOException");
                    }
                }
            } catch (SocketException e) {
                Log.e("VR", "SocketException");
            }
        }
    });
    receiveThread.start();
}
}

我使用 wireshark 来检查数据包是否正在发送,我可以看到数据包。然而,源是发送设备的 MAC 地址和目的地也像物理地址。不知道这是否相关。

有什么问题吗?

8

Hey there is an Open Source library called“Libstreaming”that is used for streaming voice / video over the network using WIFI.Just Have a look at it:

https://github.com/fyhertz/libstreaming

还提供了一些例子,请看一下:

https://github.com/fyhertz/libstreaming-examples

我已经使用该库通过网络流式传输 RTSP 音频,希望它可能有用。

3

我试着把问题分成三个部分。

Part1

通过注释与音频相关的所有内容,确保Socket Connection工作正常

Part2

只需从发送方发送任意文本消息 [Hello WiFi],然后在接收方应用程序中接收并打印它。

Part3

录音机是否实际工作?尝试在单独的项目中测试您的录制方式,看看它是否正常工作。

使用this代码捕获麦克风并播放它。

我的经验

我曾经在一个类似的项目,并测试它,我所做的是记录后,我写的记录的音频数据作为 SD 卡上的文件

(这将是原始音频,所以大多数音乐播放器将无法播放它...我猜 mPlayer 应该播放它)

2

您需要仔细考虑使用 UDP(DatagramSocket 类)作为网络协议。

UDP 是一种轻量级协议,不能保证保持接收到的数据包的顺序。这可能是音频乱码的部分原因。无序接收的数据包将导致音频数据包无序播放。在这些乱序数据包的边界,您将听到音频样本实际上已损坏的点击 / 弹出。除此之外,不能保证 UDP 数据包能够成功传递。任何丢失的数据包显然会增加任何乱码。

TCP (套接字类) 将是最佳音频质量的更好选择。TCP 是一种更健壮的协议,它将保持接收数据包的顺序。它还具有内置的错误检查功能,并将重新发送任何丢弃的数据包。但是,由于这种引人注目的功能,TCP 的网络开销更高。

我开始这个回应说,你需要仔细考虑你使用哪种协议,这是因为有一个使用的情况取决于什么对你很重要..

如果你想要超低延迟播放,但很乐意牺牲音频质量,那么 UDP 将起作用。但是,需要一些实验才能找到最佳的缓冲区和样本大小。

如果你想要最好的音频再现零失真,但很乐意引入更多的延迟,那么 TCP 是要走的路。

我不能说 TCP 会增加多少延迟。但有可能它可以在不影响用户体验的情况下实现。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(466)
自考本科教育管理专业代码:我应该读什么书才能获得计算机科学的本科教育
上一篇
服务器云平台:RDP到Windows服务器2016不工作的谷歌云平台
下一篇

相关推荐

  • android wifi传输数据提升移动体验的新方式

    Android Wifi传输数据是指使用Android手机通过Wifi网络来传输数据。实现方法有两种:使用Socket编程:…

    2023-01-08 11:59:43
    0 94 37
  • adb wifi调试:如何使用ADB Wi-Fi调试Android设备

    adb wifi调试是一种无线调试方式,它可以让开发者在不使用USB连接的情况下,通过WiFi连接来进行Android设备的调试。…

    2023-01-22 04:26:26
    0 56 50
  • 笔记本电脑发射wifi:使用WiFi显示的笔记本电脑上的Android屏幕

    关于笔记本电脑发射wifi的问题,在wife display中经常遇到,我想使用“wifi-display”在我的笔记本电脑上显示 Android 设备屏幕。根据 documentation protocol 是熟悉的 rtsp。我做了很多调试,几乎完成。我不想使用 wifi-direct.…

    2022-12-19 05:22:35
    0 65 22
  • 管理wifi:Android-管理多个Wifi连接

    关于管理wifi的问题,在2 different wifi networks中经常遇到,我在一个 Android 应用程序的设计阶段,将需要连接到多个 WiFi 网络,我想知道是否有人可以提供建议和 / 或代码段关于最好的方式去这一点。…

    2022-11-30 07:08:04
    0 43 14
  • Android应用程序与移动数据的工作方式与 wifi不同

    我有一个应用程序,它反复从 API 获取一些数据。当我有 wifi 连接时,这真的很好。但是使用移动数据,我的请求要么超时,要么花费 20 秒。这没有意义,因为如果我只是在 android 浏览器中输入 API url,它几乎立即加载。另外,API 是一个非 https api 我不知道这是否重要。任何想法可能导致这一点?我的 Ktor 客户端:…

    2022-12-04 13:37:57
    0 42 88
  • android 个推:让你的Android应用变得更加强大

    Android 个推是一个跨平台的推送服务,允许开发者在 Android 平台上发送消息给用户。它是一个基于云端的消息推送服务,可以为应用提供实时、可靠的消息推送服务。…

    2023-06-14 12:54:10
    0 26 93
  • android 开发面试题如何有效利用Android框架实现优化的用户体验?

    示例示例什么是Android?Android 是一种基于Linux的开源操作系统,主要用于移动设备,如智能手机和平板电脑。它提供了一个全面的框架,可以让开发者创建出各种各样的应用程序,从而满足用户的需求。…

    2023-05-30 15:23:42
    0 45 92
  • android启动界面:Android应用程序开发之旅

    实例实例Android启动界面是指当用户打开应用时,第一个显示的界面。它可以帮助应用程序在启动时让用户感受到良好的体验。下面是一个Android启动界面的代码实例:…

    2023-09-01 01:25:00
    0 90 98

发表评论

登录 后才能评论

评论列表(70条)