首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将音频传输到Doorbird设备

将音频传输到Doorbird设备
EN

Stack Overflow用户
提问于 2021-02-24 17:51:30
回答 1查看 119关注 0票数 2

我正在尝试创建一个Android应用程序来连接Doorbird设备,我知道该公司的官方应用程序,但我需要更多的功能来满足我的需求。

对于不知道什么是Doorbird设备的人来说,Doorbird是一款智能对讲机,Doorbird公司的产品,该设备可以通过HTTP和RTSP将音频和视频从他那里传输到任何消费者,比如Android系统,他可以获取音频流并播放它,例如,从Android设备录制音频并将其传输到Doorbird。音频采用G711 u-law.格式。

我能够从Doorbird获得视频和音频流,它工作得很好,但我没有成功地将音频传输到Doorbird。

我尝试将从Doorbird得到的相同字节传输回Doorbird,但仍然是相同的错误。

当然,我是根据他们发布的API工作的,但是没有太多关于传输音频的协议的信息。Offical Doorbird API

有没有集成Doorbird的Android项目的例子?

应该是哪种协议?

即使有人知道如何使用其他工具和系统将音频传输到Doorbird,我也会很感激。

这就是我所尝试的,我从Doorbird收到了数据(正如我所说的,它是有效的),等待了3秒钟,并用Retrofit Libray将其传输回Doorbird。

代码语言:javascript
运行
复制
    const val AUDIO_PATH =
"http://192.168.1.187/bha-api/audio-receive.cgi?http-user=XXXXXX0001&http-password=XXXXXXXXXX"
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)


    //InputStream inputStream = getResources().openRawResource(R.raw.piano12);
    val thread = Thread { this.playUrl() }
    thread.start()
    //val inStr = assets.open("doorbird_record")

}

private fun playUrl() {
    val inStr = URL(AUDIO_PATH).openStream()
    val buffer = ByteArray(1000)
    var i = 0

    //while (inStr.read(buffer).also { i = it } != -1) {


    Handler(Looper.getMainLooper()).postDelayed({
        //inStr.close()
        inStr.read(buffer)
        Log.d("DoorbirdLog", inStr.toString())
        val part = MultipartBody.Part.createFormData(
            "doorbirdStream", "doorbird", buffer.toRequestBody(
                ("audio/basic").toMediaType()
            )
        )
        //val rb = file.asRequestBody(("audio/*").toMediaType())
        val call = NetworkManager.instanceServiceApi.upload(part)
        call.enqueue(object : Callback<ResponseBody> {
            override fun onResponse(
                call: Call<ResponseBody>,
                response: Response<ResponseBody>
            ) {
                val i = response.body()
                Log.d("success", i.toString())
            }

            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                Log.d("failed", t.message.toString())
            }
        })

    }, 3000)

}

和Retrofit实例:

代码语言:javascript
运行
复制
@Multipart
@Headers( "Content-Type: audio/basic",
        "Content-Length: 9999999",
        "Connection: Keep-Alive",
        "Cache-Control: no-cache")
@POST("audio-transmit.cgi?http-user=XXXXXX0001&http-password=XXXXXXXXXX")
fun upload(@Part part: MultipartBody.Part): Call<ResponseBody>

我将感谢你的帮助

EN

回答 1

Stack Overflow用户

发布于 2021-04-21 14:56:36

最终,我找到了一个解决方案,我将在这里为那些将遇到尝试与Doorbird集成的人简要介绍这个解决方案。

代码语言:javascript
运行
复制
private const val FREQUENCY_SAMPLE_RATE_TRANSMIT = 8000
private const val RECORD_STATE_STOPPED = 0

override suspend fun recordAndTransmitAudio(audioTransmitUrl: String) =
        withContext(Dispatchers.IO) {
            val minBufferSize = AudioRecord.getMinBufferSize(
                FREQUENCY_SAMPLE_RATE_TRANSMIT, AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT
            )
            mRecorder = AudioRecord(
                MediaRecorder.AudioSource.VOICE_COMMUNICATION,
                FREQUENCY_SAMPLE_RATE_TRANSMIT, AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, minBufferSize
            )
            mRecorder?.let { enableAcousticEchoCanceler(it.audioSessionId) }
            mRecorder?.startRecording()

            val bufferShort = ShortArray(minBufferSize)
            val buffer = ByteArray(minBufferSize)

            val urlConnection = URL(audioTransmitUrl).openConnection() as HttpURLConnection
            urlConnection.apply {
                doOutput = true
                setChunkedStreamingMode(minBufferSize)
            }

            val output = DataOutputStream(urlConnection.outputStream)
            output.flush()

            try {
                mRecorder?.let { recorder ->
                    while (recorder.read(bufferShort, 0, bufferShort.size) != RECORD_STATE_STOPPED) {
                        G711UCodecManager.encode(bufferShort, minBufferSize, buffer, 0)
                        output.write(buffer)
                    }
                }
            }catch (e: Exception){
                Log.d(TAG, e.message.toString())
            }
            output.close()
            urlConnection.disconnect()
        }

which of has >首先,我们将准备录制所需的参数,并获取recording

  • Define对象的最小缓冲区大小,我们将使用该对象启动带有传输URL循环的record

  • Activate cancellation

  • And cancellation

  • And recording

  • Open连接,只要录制没有将我们录制的数据从stopped

  • Encode 16位格式转换为G.711μ-

  • ,当然,在我们完成录制后,我们清理了资源。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66348414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档