mirror of
https://github.com/F5OEO/rpitx.git
synced 2026-03-23 16:56:54 +01:00
Start processing data from pipe
ffmpeg is being weird. Wave files start with a header consisting of the text "RIFF", followed by 4 bytes for the length of the data chunk. But because we're streaming to a pipe, that value isn't known yet, so it just fills in 0xFFFFFFFF. libsndfile apparently doesn't like this and quits with the message "Error in WAV file. No 'data' chunk marker." I think I might need to drop libsndfile and manually process the data.
This commit is contained in:
@@ -8,6 +8,9 @@ import os
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
PIPE = 'pipe:1'
|
||||
DUMMY_FILE = 'dummy-file'
|
||||
|
||||
|
||||
def broadcast_fm(media_file_name, frequency):
|
||||
"""Play a media file's audio over FM."""
|
||||
@@ -29,36 +32,38 @@ def broadcast_fm(media_file_name, frequency):
|
||||
VideoCodec = libavwrapper.VideoCodec
|
||||
AudioCodec = libavwrapper.AudioCodec
|
||||
Stream = libavwrapper.AVConv
|
||||
Stream.add_option = Stream.add_parameter
|
||||
command = 'avconv'
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
'Broadcasting audio requires either avconv or ffmpeg to be installed'
|
||||
'Broadcasting audio requires either avconv or ffmpeg to be installed\n'
|
||||
'sudo apt install libav-tools'
|
||||
)
|
||||
|
||||
logger.debug('Using {}'.format(command))
|
||||
logger.debug('Using %s', command)
|
||||
|
||||
pipe_name = '/tmp/rpitx-fifo.wav'
|
||||
if not os.path.exists(pipe_name):
|
||||
os.mkfifo(pipe_name)
|
||||
input_media = Input(media_file_name)
|
||||
codec = AudioCodec('pcm_s16le').frequence(48000).channels(1)
|
||||
output_audio = Output(DUMMY_FILE, codec)
|
||||
stream = Stream(command, input_media, output_audio)
|
||||
command_line = list(stream)
|
||||
# The format needs to be specified manually because we're writing to
|
||||
# stderr and not a named file. Normally, it would infer the format from
|
||||
# the file name extension. Also, ffmpeg will only write to a pipe if it's
|
||||
# the last named argument.
|
||||
command_line.remove(DUMMY_FILE)
|
||||
command_line += ('-f', 'wav', PIPE)
|
||||
logger.debug('Running command "%s"', ' '.join(command_line))
|
||||
stream_process = subprocess.Popen(command_line, stdout=subprocess.PIPE)
|
||||
|
||||
def convert():
|
||||
"""Runs the conversion command and writes to a FIFO."""
|
||||
input_media = Input(media_file_name)
|
||||
codec = AudioCodec('pcm_s16le').frequence(48000).channels(1)
|
||||
output_audio = Output(pipe_name, codec)
|
||||
stream = Stream(command, input_media, output_audio)
|
||||
# Force overwriting existing file (it's a FIFO, that's what we want)
|
||||
if hasattr(stream, 'add_option'):
|
||||
stream.add_option('-y', '')
|
||||
else:
|
||||
stream.add_parameter('-y', '')
|
||||
logger.debug(str(stream).replace("'", '').replace(',', ''))
|
||||
def log_stdout():
|
||||
"""Log stdout from the stream process."""
|
||||
lines = stream.run()
|
||||
for line in lines:
|
||||
logger.debug(line)
|
||||
|
||||
thread = threading.Thread(target=convert)
|
||||
thread.start()
|
||||
#thread = threading.Thread(target=log_stdout).start()
|
||||
|
||||
logger.debug('Calling broadcast_fm')
|
||||
_rpitx.broadcast_fm(pipe_name, frequency)
|
||||
_rpitx.broadcast_fm(stream_process.stdout.fileno(), frequency)
|
||||
thread.join()
|
||||
|
||||
Reference in New Issue
Block a user