android - करन - वाईफाई कनेक्ट करें




वाईफाई पर एंड्रॉइड फोन के बीच स्ट्रीमिंग आवाज (2)

अरे वहाँ एक ओपन सोर्स लाइब्रेरी है जिसे "लिबस्ट्रीमिंग" कहा जाता है जिसका उपयोग वाईफ़ाई का उपयोग करके नेटवर्क पर ध्वनि / वीडियो स्ट्रीम करने के लिए किया जाता है। बस इसे देखो:

https://github.com/fyhertz/libstreaming

प्रदान किए गए कुछ उदाहरण भी हैं, कृपया इसे देखें:

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

मैंने नेटवर्क पर आरटीएसपी ऑडियो स्ट्रीम करने के लिए लाइब्रेरी का उपयोग किया है, उम्मीद है कि यह उपयोगी हो सकता है।

मैं वाईफ़ाई पर 1 एंड्रॉइड से दूसरे में माइक्रो से ऑडियो स्ट्रीम करने की कोशिश कर रहा हूं। कुछ उदाहरणों को देखने के बाद मैंने प्रत्येक में एक ही गतिविधि के साथ 2 अनुप्रयोग किए, 1 कैप्चर करने और ऑडियो भेजने के लिए और दूसरे को प्राप्त करने के लिए।

मैंने कैप्चर और प्ले करने के लिए ऑडीओरॉर्ड और ऑडिओट्रैक कक्षाओं का उपयोग किया है। हालांकि, मैं बस कुछ क्रैकिंग ध्वनि सुनता हूं (जो मैंने कुछ बदलाव किए जाने के बाद बंद कर दिया है हालांकि मैं वापस लौटा)

आवाज भेजने के लिए गतिविधि।

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_button);
    stopButton = (Button) findViewById (R.id.stop_button);

    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_button);
    stopButton = (Button) findViewById (R.id.stop_button);
    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();
}

}

मैंने यह जांचने के लिए वायरशर्क का इस्तेमाल किया कि क्या पैकेट भेजे जा रहे हैं और मैं पैकेट देख सकता हूं। स्रोत हालांकि, भेजने के उपकरण और गंतव्य का मैक पता भी एक भौतिक पते की तरह कुछ है। यह सुनिश्चित नहीं है कि यह प्रासंगिक है या नहीं।

तो क्या समस्या है?


आपको अपने नेटवर्क प्रोटोकॉल के रूप में यूडीपी (डेटाग्राम सॉकेट क्लास) के उपयोग पर ध्यान से विचार करने की आवश्यकता है।

यूडीपी एक हल्का प्रोटोकॉल है जो प्राप्त पैकेट के क्रम को बनाए रखने की गारंटी नहीं देता है। यह कारण है कि ऑडियो खराब क्यों है। ऑर्डर से प्राप्त एक पैकेट के परिणामस्वरूप ऑर्डर के बाहर ऑडियो के एक पैकेट के लायक होंगे। इन आउट-ऑफ-अनुक्रम पैकेट की सीमा पर आप क्लिक / पॉप सुनेंगे जहां ऑडियो नमूना प्रभावी रूप से भ्रष्ट है। इसके अलावा, यूडीपी पैकेट को सफलतापूर्वक वितरित करने की गारंटी नहीं है। किसी भी गिराए गए पैकेट स्पष्ट रूप से किसी भी गड़बड़ी या विरूपण को सुनाएंगे।

टीसीपी (सॉकेट क्लास) इष्टतम ऑडियो गुणवत्ता के लिए एक बेहतर विकल्प होगा। टीसीपी एक अधिक मजबूत प्रोटोकॉल है जो पैकेट प्राप्त होने वाले आदेश को बनाए रखेगा। इसमें अंतर्निहित त्रुटि जांच भी है और किसी भी गिराए गए पैकेट को फिर से भेज देगा। हालांकि, इस ध्यान की कार्यक्षमता के कारण, टीसीपी में उच्च नेटवर्क ओवरहेड है।

मैंने यह प्रतिक्रिया देकर यह प्रतिक्रिया शुरू की कि आपको सावधानीपूर्वक विचार करना होगा कि आप किस प्रोटोकॉल का उपयोग करते हैं। ऐसा इसलिए है क्योंकि आपके लिए महत्वपूर्ण क्या है इसके आधार पर या तो उपयोग करने का कोई मामला है ..

यदि आप अति कम विलंबता प्लेबैक चाहते हैं लेकिन ऑडियो गुणवत्ता को त्यागने में प्रसन्न हैं तो यूडीपी काम करेगा। हालांकि, यह सर्वोत्तम बफर और नमूना आकार खोजने के लिए कुछ प्रयोग करेगा।

यदि आप शून्य विरूपण के साथ सबसे अच्छा संभव ऑडियो पुन: उत्पादन चाहते हैं लेकिन थोड़ा अधिक विलंबता पेश करने में प्रसन्न हैं तो टीसीपी जाने का मार्ग है।

मैं नहीं कह सकता कि टीसीपी कितनी अधिक विलंबता जोड़ देगा। लेकिन यह संभव है कि इसे उपयोगकर्ता अनुभव को प्रभावित किए बिना कार्यान्वित किया जा सके। इसका पता लगाने का एकमात्र तरीका यह है कि इसे आजमाएं और देखें।





voice