AlexxIT / go2rtc

Ultimate camera streaming application with support RTSP, RTMP, HTTP-FLV, WebRTC, MSE, HLS, MP4, MJPEG, HomeKit, FFmpeg, etc.
https://github.com/AlexxIT/Blog
MIT License
7.34k stars 530 forks source link

difficulty getting two-way audio to work on Dahua clone #401

Open Cold-Lemonade opened 1 year ago

Cold-Lemonade commented 1 year ago

I have a IPC-T5241H-AS-PV camera from Andy over at EmpireTech. I got the video and audio working in go2rtc (as an add-on in Home Assistant OS), but I am having trouble getting go2rtc to stream an audio file to the camera's speaker. I'm running go2rtc v1.4.0.

Here is my go2rtc.yaml file:

streams:
  my_camera:
  - rtsp://username:password@ip_address:554/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif
  - ffmpeg:my_camera#audio=aac

I can get camera's audio feed to play using MSE, but not WebRTC. Otherwise, everything seems to fine.

To stream an audio file to the camera, I've tried issuing the following command in my Home Assistant's terminal (command line).

curl -X POST http://localhost:1984/api/streams\?dst=my_camera\&src\=ffmpeg:/media/local/audio_file.wav\#audio\=pcma/48000

But this yields the following message: exec: exit status 1

When I listen to the camera's speaker when I run this command, it sounds like the camera is trying to play something, but it is static (white noise).

I am a newbie with linux and figure something is wrong with how I am calling POST.

Any thoughts?

NickM-27 commented 1 year ago

I can get camera's audio feed to play using MSE, but not WebRTC. Otherwise, everything seems to fine.

What audio codec is the cameras audio set to in the settings?

curl -X POST http://localhost:1984/api/streams\?dst=my_camera\&src\=ffmpeg:/media/local/audio_file.wav\#audio\=pcma/48000

where are you trying to play this? Does go2rtc have access to the file? You also haven't applied the #input=file which should be necessary

Cold-Lemonade commented 1 year ago

Hi @NickM-27

I'm trying to play the audio file on the camera's speaker from my RPi4 that runs Home Assistant with the go2rtc add-on. The audio file is in the local media folder on the RPi4 and can be seen in Home Assistant so I assume go2rtc has access to it.

Inside the camera, I have the audio encoding set to AAC with a sampling frequency of 8000. I think the wav file has a sampling frequency of 48000. I've also just changed the encoding inside the camera to AAC with a sampling frequency of 48000 and it makes no difference.

I've tried it with and without #input=file and there's no difference.

Everytime I try it, I get static on the camera's speaker for the duration of the wav file and the same exec: exit status 1 message.

Any suggestions?

I've tried it with

NickM-27 commented 1 year ago

You should enable trace logs for exec so you can see the reason for failure

NickM-27 commented 1 year ago

Also I think you're mixing up the cameras output and input. You should check the go2rtc info page for what the camera expects from recvonly, it's probably PCMA 8000

Cold-Lemonade commented 1 year ago

You should enable trace logs for exec so you can see the reason for failure

Thank you for your guidance. Being a newbie, I am not sure how to turn on the logging. Can you please direct me on how to do that?

Cold-Lemonade commented 1 year ago

Also I think you're mixing up the cameras output and input. You should check the go2rtc info page for what the camera expects from recvonly, it's probably PCMA 8000

I don't think there is a limitation for go2rtc. Instead, I think it is limited by the camera's ability. Also, if I'm reading the go2rtc info page correctly, I think the encoding is determined by the call to ffmpeg in the go2rtc config. But I could be mistaken. Again, I'm really new to all this.

Many thanks for your help.

Cold-Lemonade commented 1 year ago

@NickM-27 I feel pretty stupid. The path to my wav file was wrong. It was just /media/audio_file.wav. Now I'm getting a "can't find consumer" error.

NickM-27 commented 1 year ago

Also I think you're mixing up the cameras output and input. You should check the go2rtc info page for what the camera expects from recvonly, it's probably PCMA 8000

I don't think there is a limitation for go2rtc. Instead, I think it is limited by the camera's ability. Also, if I'm reading the go2rtc info page correctly, I think the encoding is determined by the call to ffmpeg in the go2rtc config. But I could be mistaken. Again, I'm really new to all this.

Many thanks for your help.

That is incorrect. The camera only has specific codecs / sampling frequencies that it can play. You must use ffmpeg to convert the audio file to one of those for the camera to play.

Cold-Lemonade commented 1 year ago

Also I think you're mixing up the cameras output and input. You should check the go2rtc info page for what the camera expects from recvonly, it's probably PCMA 8000

I don't think there is a limitation for go2rtc. Instead, I think it is limited by the camera's ability. Also, if I'm reading the go2rtc info page correctly, I think the encoding is determined by the call to ffmpeg in the go2rtc config. But I could be mistaken. Again, I'm really new to all this. Many thanks for your help.

That is incorrect. The camera only has specific codecs / sampling frequencies that it can play. You must use ffmpeg to convert the audio file to one of those for the camera to play.

I think we're saying the same thing.

NickM-27 commented 1 year ago

paste the camera info

Cold-Lemonade commented 1 year ago

These are the audio compression encodings according to the Dahau website ():

PCM G.711a G.711Mu G.726 G.723

When I look at my audio encoding options in the camera's GUI, I have: PCM G.711a G.711Mu G.726 AAC G.773

Here's what the info page says:

Device TypeIPC-T5241H-AS-PV-3.6mm
System VersionV2.800.0000000.19.R, Build Date: 2020-07-09
WEB VersionV3.2.1.919770
ONVIF Version19.06(V2.6.1.887698)
S/N **************************
Algorithm Version1.0.1
Security Baseline VersionV2.1
NickM-27 commented 1 year ago

We need the info from go2rtc info page

Cold-Lemonade commented 1 year ago

Sorry. I misunderstood.

  "producers": [
    {
      "url": "rtsp://username:password@ip_address:554/cam/realmonitor?channel=1\u0026subtype=0\u0026unicast=true\u0026proto=Onvif"
    },
    {
      "url": "ffmpeg:my_camera#audio=mycodec"
    }
  ],
  "consumers": []
}

I defined mycodec in the go2rtc config file to match the encoding in the camera.

ffmpeg:
  mycodec: "-c:a aac -ar:a 64000 -ac:a 1"

I'm wondering why the "consumer" section of my camera's info is blank. Could that be part of the issue?

Also, when I try to play an m4a file, the camera chirps and I no longer get any "can't find consumer" message in the terminal display. Instead, it outputs a bunch of stuff that looks like the camera info, with stuff like "producers" "receivers" "consumers" etc.

NickM-27 commented 1 year ago

Also, when I try to play an m4a file, the camera chirps and I no longer get any "can't find consumer" message in the terminal display. Instead, it outputs a bunch of stuff that looks like the camera info, with stuff like "producers" "receivers" "consumers" etc.

that's what we need to see

Cold-Lemonade commented 1 year ago

Here's what the terminal spits out... I'm having difficulty copying-and-pasting it out of terminal. So this is from OCR on my smart phone:

"producers": [("ur]":"rtsp://username:password@ip_address:554/cam/realmonitor?channel-1\u0026subtype-0\u0026unicast-truelu0026proto-Onvif"), ("url":"ffmpeg:my_camera#audio=mycodec"),{"type":"RTSP passive producer", "url":"rtsp://localhost: 8554/d42b52586ed927de1d302fdf9313941b","remote_addr":"[::1]:50456", "user_agent":"ffmpeg/go2rtc", "medias": ["audio, recvonly, MPEG4-GENERIC/48000/2"], "receivers": ["96 MPEG4-GENERIC/48000/2, bytes-0, senders=1"], "recv": 28}], "consumers": [{"type":"RTSP active producer", "url":"rtsp: //ip_address:554/cam/realmonitor?channel-1\u0026subtype0\u0026unicast-true\u0026proto-Onvif/", "remote_addr":"ip_address:554", "user _agent"; "go2rtc/1.4.0", "medias": ["video, recvonly, H.264 Main 4.2", "audio, recvonly, MPEG4-GENERIC/64000", "application, revonly, VND.ONVIF METADATA"," audio, sendonly, L16/8000, L16/16000, L16/32000, L16/48000, L16/64000, PCM/8000, PCMA/16000, PCMA/32000, PCM/48000, POMA/64000, PCMJ/8000, PCM/16000, PCMU/32000 , POMU/48000, PCMU/64000, G726-40/8000, G726-40/16000, G726-40/32000, G726-40/48000, G726-40/64000, MPEG4-GENERIC/8000, MPEG4-GENERIC/16000, MPEG4-GENERIC/32000, M PEGA-GENERIC/48000, MPEGA-GENERIC/64000, 122, 123, 124, 125, 126"], "senders": ("120 MPEGA-GENERIC/48000, bytes=0, receivers=1"]}]}
Cold-Lemonade commented 1 year ago

This is probably a better version. I grabbed it while the curl -X POST command was being issued:

{
  "producers": [
    {
      "url": "rtsp://username:password@ip_address:554/cam/realmonitor?channel=1\u0026subtype=0\u0026unicast=true\u0026proto=Onvif"
    },
    {
      "url": "ffmpeg:my_camera#audio=mycodec"
    },
    {
      "type": "RTSP passive producer",
      "url": "rtsp://localhost:8554/d42b52586ed927de1d302fdf9313941b",
      "remote_addr": "[::1]:48528",
      "user_agent": "ffmpeg/go2rtc",
      "medias": [
        "audio, recvonly, MPEG4-GENERIC/48000/2"
      ],
      "receivers": [
        "96 MPEG4-GENERIC/48000/2, bytes=104347, senders=1"
      ],
      "recv": 105587
    }
  ],
  "consumers": [
    {
      "type": "RTSP active producer",
      "url": "rtsp://ip_address:554/cam/realmonitor?channel=1\u0026subtype=0\u0026unicast=true\u0026proto=Onvif/",
      "remote_addr": "ip_address:554",
      "user_agent": "go2rtc/1.4.0",
      "medias": [
        "video, recvonly, H.264 Main 4.2",
        "audio, recvonly, MPEG4-GENERIC/64000",
        "application, recvonly, VND.ONVIF.METADATA",
        "audio, sendonly, L16/8000, L16/16000, L16/32000, L16/48000, L16/64000, PCMA/8000, PCMA/16000, PCMA/32000, PCMA/48000, PCMA/64000, PCMU/8000, PCMU/16000, PCMU/32000, PCMU/48000, PCMU/64000, G726-40/8000, G726-40/16000, G726-40/32000, G726-40/48000, G726-40/64000, MPEG4-GENERIC/8000, MPEG4-GENERIC/16000, MPEG4-GENERIC/32000, MPEG4-GENERIC/48000, MPEG4-GENERIC/64000, 122, 123, 124, 125, 126"
      ],
      "senders": [
        "120 MPEG4-GENERIC/48000, bytes=104347, receivers=1"
      ],
      "send": 105963
    }
  ]
}
Cold-Lemonade commented 1 year ago

I've re-encoded the audio file using Audacity with a sampling frequency of 64000 so the "senders" matches the recvonly. But it doesn't change anything. The camera just makes a weird chirping sound a couple of times.

NickM-27 commented 1 year ago

That's incorrect, you're using the producer which in this case is just the ffmpeg command. You simply need to start watching a stream from that camera in go2rtc and get the info from there, that will show what we need to see.

Cold-Lemonade commented 1 year ago

Thank you for the clarification. I've grabbed the camera info with a stream from it open on go2rtc. Here it is:

{
  "producers": [
    {
      "type": "RTSP active producer",
      "url": "rtsp://camera_ip_address:554/cam/realmonitor?channel=1\u0026subtype=0\u0026unicast=true\u0026proto=Onvif/",
      "remote_addr": "camera_ip_address:554",
      "user_agent": "go2rtc/1.4.0",
      "medias": [
        "video, recvonly, H.264 Main 4.2",
        "audio, recvonly, MPEG4-GENERIC/64000",
        "application, recvonly, VND.ONVIF.METADATA",
        "audio, sendonly, L16/8000, L16/16000, L16/32000, L16/48000, L16/64000, PCMA/8000, PCMA/16000, PCMA/32000, PCMA/48000, PCMA/64000, PCMU/8000, PCMU/16000, PCMU/32000, PCMU/48000, PCMU/64000, G726-40/8000, G726-40/16000, G726-40/32000, G726-40/48000, G726-40/64000, MPEG4-GENERIC/8000, MPEG4-GENERIC/16000, MPEG4-GENERIC/32000, MPEG4-GENERIC/48000, MPEG4-GENERIC/64000, 122, 123, 124, 125, 126"
      ],
      "receivers": [
        "96 H264, bytes=1880656, senders=2",
        "97 MPEG4-GENERIC/64000, bytes=86295, senders=1"
      ],
      "recv": 1987591
    },
    {
      "url": "ffmpeg:my_camera#audio=mycodec"
    }
  ],
  "consumers": [
    {
      "type": "MP4 passive consumer",
      "remote_addr": "laptop_ip_address:60904",
      "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.64",
      "medias": [
        "video, sendonly, H264, H265",
        "audio, sendonly, MPEG4-GENERIC, PCMA, PCMU, L16, OPUS"
      ],
      "senders": [
        "96 H264, bytes=1880656, receivers=1",
        "97 MPEG4-GENERIC/64000, bytes=86295, receivers=1"
      ],
      "send": 2010483
    },
    {
      "type": "WebRTC/WebSocket async passive consumer",
      "remote_addr": "udp4 prflx laptop_ip_address:63426 related :0",
      "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.64",
      "medias": [
        "video, sendonly, VP8, RTX, VP9, H264, AV1, RED, ULPFEC, FLEXFEC-03",
        "audio, sendonly, OPUS/48000/2, RED/48000/2, G722/8000, PCMU/8000, PCMA/8000, CN/8000, TELEPHONE-EVENT/48000, TELEPHONE-EVENT/8000, L16"
      ],
      "senders": [
        "102 H264, bytes=1880656, receivers=1"
      ],
      "send": 1900927
    }
  ]
}
NickM-27 commented 1 year ago

Looks like the camera supports lots of audio types. I'd suggest doing pcma/8000 since it's simpler and a good starting point, but the camera may have issues playing some audio types so have to experiment.

Cold-Lemonade commented 1 year ago

Thank you @NickM-27 How do I specify that pcma/8000? Do I need to create an ffmpeg: section in my config file? Or do I just do it in the curl -X POST command in terminal?

NickM-27 commented 1 year ago

#audio=pcmu in the curl command.

Cold-Lemonade commented 1 year ago

So I ran the following command in terminal and the camera just chirps a couple of times. Nothing else.

curl -X POST http://localhost:1984/api/streams\?dst=my_camera\&src\=ffmpeg:/media/audio_file.m4a\#audio\=pcmu\#input\=file

Same thing if I try #audio\=pcma

NickM-27 commented 1 year ago

The camera doesn't like something, hard to say what

Cold-Lemonade commented 1 year ago

Is the syntax of my curl -X POST command correct?

NickM-27 commented 1 year ago

I think so but I've not tried it with curl. I'd suggest just using the go2rtc webUI to send it

Cold-Lemonade commented 1 year ago

@NickM-27 That works with pcma! So it must be an issue with my curl command.

Cold-Lemonade commented 1 year ago

@AlexxIT How do you recommend making the POST request from the command line in Home Assistant to stream an audio file to the camera?

Cold-Lemonade commented 1 year ago

@NickM-27 I got it to work from the command line!

curl does not like the hash in the url. So it needs to be replaced with %23. In case others run into the same problem, here is the generic curl command that I issued in the Home Assistant terminal that worked for me using pcma/48000 encoding. This assumes your audio file is located in the /media folder.

curl -X POST http://localhost:1984/api/streams\?dst\=my_camera\&src\=ffmpeg:/media/audio_file.m4a%23audio\=pcma/48000%23input\=file
AlexxIT commented 1 year ago

Yes. Hash symbol is not valid symbol for URLs. Thats why I'm using it for FFmpeg source. So go2rtc can always know where URL ends and where FFmpeg params starts.

I think I need to make some easier API for playing URLs with autodetection supported codecs and autouse of ffmpeg source with right arguments :)