PipeOutputPlugin.cxx 2.02 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright 2003-2017 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
14 15 16 17
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 19
 */

20
#include "config.h"
21
#include "PipeOutputPlugin.hxx"
22
#include "../OutputAPI.hxx"
23
#include "system/Error.hxx"
24

25
#include <string>
26
#include <stdexcept>
27

28 29
#include <stdio.h>

30
class PipeOutput final : AudioOutput {
31
	const std::string cmd;
32
	FILE *fh;
33

34
	PipeOutput(const ConfigBlock &block);
35

36
public:
37 38 39 40
	static AudioOutput *Create(EventLoop &,
				   const ConfigBlock &block) {
		return new PipeOutput(block);
	}
41

42 43
private:
	void Open(AudioFormat &audio_format) override;
44

45
	void Close() noexcept override {
46 47 48
		pclose(fh);
	}

49
	size_t Play(const void *chunk, size_t size) override;
50 51
};

52
PipeOutput::PipeOutput(const ConfigBlock &block)
53
	:AudioOutput(0),
54
	 cmd(block.GetBlockValue("command", ""))
55
{
56 57
	if (cmd.empty())
		throw std::runtime_error("No \"command\" parameter specified");
58 59
}

60 61
inline void
PipeOutput::Open(gcc_unused AudioFormat &audio_format)
62
{
63
	fh = popen(cmd.c_str(), "w");
64 65
	if (fh == nullptr)
		throw FormatErrno("Error opening pipe \"%s\"", cmd.c_str());
66 67
}

68
inline size_t
69
PipeOutput::Play(const void *chunk, size_t size)
70 71 72
{
	size_t nbytes = fwrite(chunk, 1, size, fh);
	if (nbytes == 0)
73
		throw MakeErrno("Write error on pipe");
74 75

	return nbytes;
76 77
}

78
const struct AudioOutputPlugin pipe_output_plugin = {
79 80
	"pipe",
	nullptr,
81
	&PipeOutput::Create,
82
	nullptr,
83
};