muammar / mkchromecast

Cast macOS and Linux Audio/Video to your Google Cast and Sonos Devices
http://mkchromecast.com
Other
2.23k stars 140 forks source link

Streaming from line-in on a Raspberry Pi #279

Open mph070770 opened 5 years ago

mph070770 commented 5 years ago

Hi. I have a USB soundcard connected to my Rpi. I'd like to be able to cast from the line-in of the soundcard to a group of speakers, with minimal delay, and good quality. Can anyone advise on the best setup?

I've been trying to get this working today. Here's my config. If anyone can suggest how to get it working - that would be great. I get the same issue as others have struggled with - the connection beep happens and I can change volume, just no audio:

On a fresh install of Rpi buster:

sudo apt-get install mkchromecast-alsa

I then setup the loopback:

sudo modprobe snd-aloop

Then, my soundcards look like this:

 0 [ALSA           ]: bcm2835_alsa - bcm2835 ALSA
                      bcm2835 ALSA
 1 [Device         ]: USB-Audio - USB Audio Device
                      GeneralPlus USB Audio Device at usb-3f980000.usb-1.5, full speed
 2 [Loopback       ]: Loopback - Loopback
                      Loopback 1

So, I assume my X1,Y1 is 1,0 and my X2,Y2 is 2,0.

My .asoundrc is as follows:

pcm.!default {
  type asym
  playback.pcm "LoopAndReal"
  #capture.pcm "looprec"
  capture.pcm "hw:1,0"
}

pcm.looprec {
    type hw
    card "Loopback"
    device 1
    subdevice 0
}

pcm.LoopAndReal {
  type plug
  slave.pcm mdev
  route_policy "duplicate"
}

pcm.mdev {
  type multi
  slaves.a.pcm pcm.MixReale
  slaves.a.channels 2
  slaves.b.pcm pcm.MixLoopback
  slaves.b.channels 2
  bindings.0.slave a
  bindings.0.channel 0
  bindings.1.slave a
  bindings.1.channel 1
  bindings.2.slave b
  bindings.2.channel 0
  bindings.3.slave b
  bindings.3.channel 1
}

pcm.MixReale {
  type dmix
  ipc_key 1024
  slave {
    pcm "hw:1,0"
    rate 48000
    #rate 44100
    periods 128
    period_time 0
    period_size 1024 # must be power of 2
    buffer_size 8192
  }
}

pcm.MixLoopback {
  type dmix
  ipc_key 1025
  slave {
    pcm "hw:Loopback,0,0"
    rate 48000
    #rate 44100
    periods 128
    period_time 0
    period_size 1024 # must be power of 2
    buffer_size 8192
  }
}

QUESTION: Is it correct that pcm.looprec is device 1, subdevice 0?

Running mkchromecast (where I want the line in input of the USB to output to the chromecast speaker), I get the following:

pi@raspberrypi:~ $ mkchromecast --encoder-backend ffmpeg --alsa-device hw:2,1 -c aac --volume --debug
ALSA device name: hw:2,1.
Google Cast name: None.
backends:  ['ffmpeg', 'avconv', 'parec', 'gstreamer']
The --volume flag is going to be renamed to           --control.
ALSA device name: hw:2,1.
Google Cast name: None.
backends:  ['ffmpeg', 'avconv', 'parec', 'gstreamer']
The --volume flag is going to be renamed to           --control.
USER =pi
PATH =/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
Mkchromecast v0.3.8.1
:::cast::: sockets method 192.168.0.116
Starting Local Streaming Server
[Done]
:::audio::: chunk_size, frame_size, buffer_size: 64, 2048, 8192
Selected backend: ffmpeg
Selected audio codec: aac
Default bitrate used: 192k
Default sample rate used: 44100Hz.
['ffmpeg', '-ac', '2', '-ar', '44100', '-frame_size', '2048', '-fragment_size', '2048', '-f', 'alsa', '-i', 'hw:2,1', '-f', 'adts', '-acodec', 'aac', '-ac', '2', '-ar', '44100', '-b:a', '192k', '-cutoff', '18000', 'pipe:']
:::audio::: command ['ffmpeg', '-ac', '2', '-ar', '44100', '-frame_size', '2048', '-fragment_size', '2048', '-f', 'alsa', '-i', 'hw:2,1', '-f', 'adts', '-acodec', 'aac', '-ac', '2', '-ar', '44100', '-b:a', '192k', '-cutoff', '18000', 'pipe:']
 * Serving Flask app "mkchromecast.audio" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
PID of main process: 2657
   Use a production WSGI server instead.
PID of streaming process: 2662
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
self.cclist [[0, 'Living Room Speaker', 'Gcast']]
if len(self.cclist) != 0 and self.select_cc == False:

List of Devices Available in Network:
-------------------------------------

Index   Types   Friendly Name 
=====   =====   ============= 
0   Gcast   Living Room Speaker

Casting to first device shown above!
Select devices by using the -s flag.

Living Room Speaker

def get_cc(self):

Information about  Living Room Speaker

DeviceStatus(friendly_name='Living Room Speaker', model_name='Google Home Max', manufacturer='Unknown manufacturer', uuid=UUID('xx-xx'), cast_type='cast')

Status of device  Living Room Speaker

CastStatus(is_active_input=False, is_stand_by=True, volume_level=0.4000000059604645, volume_muted=False, app_id=None, display_name=None, namespaces=[], session_id=None, transport_id=None, status_text='')

def play_cast(self):
The IP of Living Room Speaker is: 192.168.0.105
Your local IP is: 192.168.0.116

The media type string used is: audio/aac

Cast media controller status

CastStatus(is_active_input=False, is_stand_by=True, volume_level=0.4000000059604645, volume_muted=False, app_id=None, display_name=None, namespaces=[], session_id=None, transport_id=None, status_text='')

Controls:
=========

Volume Up: u
Volume Down: d
Quit the Application: q or Ctrl-C

ffmpeg version 4.1.4-1+rpt1~deb10u1 Copyright (c) 2000-2019 the FFmpeg developers
                                                                                   built with gcc 8 (Raspbian 8.3.0-6+rpi1)
                                                                                                                             configuration: --prefix=/usr --extra-version='1+rpt1~deb10u1' --toolchain=hardened --libdir=/usr/lib/arm-linux-gnueabihf --incdir=/usr/include/arm-linux-gnueabihf --arch=arm --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-omx-rpi --enable-mmal --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
                                                                                       libavutil      56. 22.100 / 56. 22.100
                                                                                                                               libavcodec     58. 35.100 / 58. 35.100
                                                                                                                                                                       libavformat    58. 20.100 / 58. 20.100
                        libavdevice    58.  5.100 / 58.  5.100
                                                                libavfilter     7. 40.101 /  7. 40.101
                                                                                                        libavresample   4.  0.  0 /  4.  0.  0
                                                                                                                                                libswscale      5.  3.100 /  5.  3.100
                                                                                                                                                                                        libswresample   3.  3.100 /  3.  3.100
                                         libpostproc    55.  3.100 / 55.  3.100
                                                                               Option fragment_size not found.
192.168.0.105 - - [07/Oct/2019 17:41:54] "GET /stream HTTP/1.1" 200 -

I then tried by inputting an mp3 file:

pi@raspberrypi:~ $ mkchromecast -i "test.mp3" --encoder-backend ffmpeg --alsa-device hw:2,1 -c aac --volume
The --volume flag is going to be renamed to           --control.
The --volume flag is going to be renamed to           --control.
Mkchromecast v0.3.8.1
Starting Local Streaming Server
[Done]
Selected backend: ffmpeg
Selected audio codec: aac
Default bitrate used: 192k
Default sample rate used: 44100Hz.
['ffmpeg', '-ac', '2', '-ar', '44100', '-frame_size', '2048', '-fragment_size', '2048', '-f', 'alsa', '-i', 'hw:2,1', '-f', 'adts', '-acodec', 'aac', '-ac', '2', '-ar', '44100', '-b:a', '192k', '-cutoff', '18000', 'pipe:']
 * Serving Flask app "mkchromecast.audio" (lazy loading)
PID of main process: 2671
 * Environment: production
PID of streaming process: 2676
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

List of Devices Available in Network:
-------------------------------------

Index   Types   Friendly Name 
=====   =====   ============= 
0   Gcast   Living Room Speaker

Casting to first device shown above!
Select devices by using the -s flag.

Living Room Speaker

Information about  Living Room Speaker

DeviceStatus(friendly_name='Living Room Speaker', model_name='Google Home Max', manufacturer='Unknown manufacturer', uuid=UUID('xx-xx'), cast_type='cast')

Status of device  Living Room Speaker

CastStatus(is_active_input=False, is_stand_by=True, volume_level=0.4000000059604645, volume_muted=False, app_id=None, display_name=None, namespaces=[], session_id=None, transport_id=None, status_text='')

The IP of Living Room Speaker is: 192.168.0.105
Your local IP is: 192.168.0.116

The media type string used is: audio/aac

Cast media controller status

CastStatus(is_active_input=False, is_stand_by=True, volume_level=0.4000000059604645, volume_muted=False, app_id=None, display_name=None, namespaces=[], session_id=None, transport_id=None, status_text='')

Controls:
=========

Volume Up: u
Volume Down: d
Quit the Application: q or Ctrl-C

192.168.0.105 - - [07/Oct/2019 17:43:32] "GET /stream HTTP/1.1" 200 -

Any suggestions of where my setup is wrong?

mph070770 commented 5 years ago

Ok, got a bit further (maybe). It seems that the message above "Option fragment_size not found." means that ffmeg doesn't work. As a hack, I removed it from the audio.py source of mkchromecast. Now ffmpeg runs but I still don't have audio - but I may have broken something else - so will go back and check...

Question: is my calling of mkchromecast wrong or is mkchromecast calling ffmpeg incorrectly?

Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, alsa, from 'hw:1,1':
  Duration: N/A, start: 1570471681.289849, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
Output #0, adts, to 'pipe:':
  Metadata:
    encoder         : Lavf58.20.100
    Stream #0:0: Audio: aac (LC), 44100 Hz, stereo, fltp, 192 kb/s
    Metadata:
      encoder         : Lavc58.35.100 aac
192.168.0.105 - - [07/Oct/2019 19:08:01] "GET /stream HTTP/1.1" 200 -
Cleaning up /tmp/...=00:01:10.98 bitrate=   4.5kbits/s speed=0.999x    
khaffner commented 5 years ago

I'm planning to do exactly this, have you had any progress?

genevera commented 4 years ago

Maybe using sox to shuttle the sound between devices will work better?

edent commented 4 years ago

Anyone managed to solve this?

I've tried running mkchromecast --encoder-backend ffmpeg --alsa-device hw:0,0 and hw:2,0. Both turn on my ChromeCast, I can control the volume, but no audio comes out.

I can record audio with arecord --device="hw:2,0 but I can't seem to stream it.