Recording kinda working but not quite
This commit is contained in:
parent
b347a8e22b
commit
efee6d3ef4
35
examples/record-app.php
Normal file
35
examples/record-app.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__."/../vendor/autoload.php";
|
||||||
|
|
||||||
|
use NoccyLabs\PulseAudio\PulseAudio;
|
||||||
|
|
||||||
|
$pulse = new PulseAudio();
|
||||||
|
|
||||||
|
// Find the client
|
||||||
|
$inputs = $pulse->getSinkInputs();
|
||||||
|
foreach ($inputs as $input) {
|
||||||
|
if ($input->getProperty('application.name') == 'Audacious') {
|
||||||
|
echo "Found audacious on input #".$input->getIndex()."\n";
|
||||||
|
record($pulse, $input, "output.wav");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function record($pulse, $input, $filename)
|
||||||
|
{
|
||||||
|
echo "Creating null sink...\n";
|
||||||
|
$recSink = $pulse->createNullSink();
|
||||||
|
|
||||||
|
echo "Creating recorder...\n";
|
||||||
|
$recorder = $recSink->createRecorder();
|
||||||
|
$recorder->setFilename($filename);
|
||||||
|
|
||||||
|
echo "Moving audacious to the null sink with index #".$recSink->getIndex()."...\n";
|
||||||
|
$input->moveToSink($recSink);
|
||||||
|
|
||||||
|
echo "Recording 5 seconds...\n";
|
||||||
|
$recorder->start();
|
||||||
|
sleep(5);
|
||||||
|
$recorder->stop();
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,8 @@ class Pacmd
|
|||||||
$cmdl = array_merge([ $command ], $args);
|
$cmdl = array_merge([ $command ], $args);
|
||||||
$cmdl = join(" ", array_map("escapeshellarg", $cmdl));
|
$cmdl = join(" ", array_map("escapeshellarg", $cmdl));
|
||||||
|
|
||||||
|
echo "$ pacmd {$cmdl}\n";
|
||||||
|
|
||||||
// call pacmd
|
// call pacmd
|
||||||
exec("pacmd {$cmdl}", $output, $retval);
|
exec("pacmd {$cmdl}", $output, $retval);
|
||||||
|
|
||||||
@ -29,105 +31,10 @@ class Pacmd
|
|||||||
$status = array_shift($output);
|
$status = array_shift($output);
|
||||||
// printf("[pacmd] %s\n", $status);
|
// printf("[pacmd] %s\n", $status);
|
||||||
|
|
||||||
$parser = new ListParser();
|
$parser = new PacmdListParser();
|
||||||
$output = $parser->parse($output);
|
$output = $parser->parse($output);
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ListParser
|
|
||||||
{
|
|
||||||
public function parse(array $lines)
|
|
||||||
{
|
|
||||||
$lines = $this->prepare($lines);
|
|
||||||
return $this->parseRecursive($lines, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function prepare(array $lines)
|
|
||||||
{
|
|
||||||
$data = [];
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
if ($line=="") continue;
|
|
||||||
if ($line[0] == " ") {
|
|
||||||
$data[] = [ 0, trim($line) ];
|
|
||||||
} else {
|
|
||||||
$depth = 0;
|
|
||||||
while ($line[0]=="\t") {
|
|
||||||
$depth++;
|
|
||||||
$line = substr($line,1);
|
|
||||||
}
|
|
||||||
$data[] = [ $depth, $line ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function parseRecursive(array $lines, $current=0)
|
|
||||||
{
|
|
||||||
$ret = [];
|
|
||||||
while (count($lines)>0) {
|
|
||||||
$line = array_shift($lines);
|
|
||||||
$children = [];
|
|
||||||
while ((count($lines)>0) && ($lines[0][0]>$current)) {
|
|
||||||
$children[] = array_shift($lines);
|
|
||||||
}
|
|
||||||
if (count($children)>0) {
|
|
||||||
$key = trim(str_replace("index: ","", $line[1]),":* ");
|
|
||||||
$ret[$key] = $this->parseRecursive($children, $line[0]+1);
|
|
||||||
} else {
|
|
||||||
if (strpos($line[1]," = ")!==false) {
|
|
||||||
list ($k,$v) = array_map("trim", explode("=",$line[1],2));
|
|
||||||
$ret[$k] = $this->parseVal($v);
|
|
||||||
} elseif (strpos($line[1],": ")!==false) {
|
|
||||||
list ($k,$v) = array_map("trim", explode(":",$line[1],2));
|
|
||||||
$ret[$k] = $this->parseVal($v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function parseVal($value)
|
|
||||||
{
|
|
||||||
if ($value=="") {
|
|
||||||
return null;
|
|
||||||
} elseif ($value=="yes") {
|
|
||||||
return true;
|
|
||||||
} elseif ($value=="no") {
|
|
||||||
return false;
|
|
||||||
} elseif ($value[0]=="<") {
|
|
||||||
$kvs = trim($value,"<>");
|
|
||||||
if (strpos($kvs,"=")===false) {
|
|
||||||
return $kvs;
|
|
||||||
}
|
|
||||||
$kvs = explode(" ",$kvs);
|
|
||||||
$val = [];
|
|
||||||
foreach ($kvs as $kv) {
|
|
||||||
list ($k,$v) = explode("=",$kv,2);
|
|
||||||
$val[$k] = $v;
|
|
||||||
}
|
|
||||||
return $val;
|
|
||||||
} elseif ($value[0]=="\"") {
|
|
||||||
return trim($value,"\"");
|
|
||||||
} else {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function parseKeyVal($kvs)
|
|
||||||
{
|
|
||||||
$kvs = explode(" ",$kvs,2 );
|
|
||||||
$val = [];
|
|
||||||
foreach ($kvs as $kv) {
|
|
||||||
list ($k,$v) = explode("=",$kv,2);
|
|
||||||
$val[$k] = $this->parseKeyVal($v);
|
|
||||||
}
|
|
||||||
return $val;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
100
src/Helper/PacmdListParser.php
Normal file
100
src/Helper/PacmdListParser.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace NoccyLabs\PulseAudio\Helper;
|
||||||
|
|
||||||
|
class PacmdListParser
|
||||||
|
{
|
||||||
|
public function parse(array $lines)
|
||||||
|
{
|
||||||
|
$lines = $this->prepare($lines);
|
||||||
|
return $this->parseRecursive($lines, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function prepare(array $lines)
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
if ($line=="") continue;
|
||||||
|
if ($line[0] == " ") {
|
||||||
|
$data[] = [ 0, trim($line) ];
|
||||||
|
} else {
|
||||||
|
$depth = 0;
|
||||||
|
while ($line[0]=="\t") {
|
||||||
|
$depth++;
|
||||||
|
$line = substr($line,1);
|
||||||
|
}
|
||||||
|
$data[] = [ $depth, $line ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseRecursive(array $lines, $current=0)
|
||||||
|
{
|
||||||
|
$ret = [];
|
||||||
|
while (count($lines)>0) {
|
||||||
|
$line = array_shift($lines);
|
||||||
|
$children = [];
|
||||||
|
while ((count($lines)>0) && ($lines[0][0]>$current)) {
|
||||||
|
$children[] = array_shift($lines);
|
||||||
|
}
|
||||||
|
if (count($children)>0) {
|
||||||
|
$key = trim(str_replace("index: ","", $line[1]),":* ");
|
||||||
|
$ret[$key] = $this->parseRecursive($children, $line[0]+1);
|
||||||
|
} else {
|
||||||
|
if (strpos($line[1]," = ")!==false) {
|
||||||
|
list ($k,$v) = array_map("trim", explode("=",$line[1],2));
|
||||||
|
$ret[$k] = $this->parseVal($v);
|
||||||
|
} elseif (strpos($line[1],": ")!==false) {
|
||||||
|
list ($k,$v) = array_map("trim", explode(":",$line[1],2));
|
||||||
|
$ret[$k] = $this->parseVal($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseVal($value)
|
||||||
|
{
|
||||||
|
if ($value=="") {
|
||||||
|
return null;
|
||||||
|
} elseif ($value=="yes") {
|
||||||
|
return true;
|
||||||
|
} elseif ($value=="no") {
|
||||||
|
return false;
|
||||||
|
} elseif ($value[0]=="<") {
|
||||||
|
$kvs = trim($value,"<>");
|
||||||
|
if (strpos($kvs,"=")===false) {
|
||||||
|
return $kvs;
|
||||||
|
}
|
||||||
|
$kvs = explode(" ",$kvs);
|
||||||
|
$val = [];
|
||||||
|
foreach ($kvs as $kv) {
|
||||||
|
list ($k,$v) = explode("=",$kv,2);
|
||||||
|
$val[$k] = $v;
|
||||||
|
}
|
||||||
|
return $val;
|
||||||
|
} elseif ($value[0]=="\"") {
|
||||||
|
return trim($value,"\"");
|
||||||
|
} else {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseKeyVal($kvs)
|
||||||
|
{
|
||||||
|
$kvs = explode(" ",$kvs,2 );
|
||||||
|
$val = [];
|
||||||
|
foreach ($kvs as $kv) {
|
||||||
|
list ($k,$v) = explode("=",$kv,2);
|
||||||
|
$val[$k] = $this->parseKeyVal($v);
|
||||||
|
}
|
||||||
|
return $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
29
src/Helper/Pactl.php
Normal file
29
src/Helper/Pactl.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace NoccyLabs\PulseAudio\Helper;
|
||||||
|
|
||||||
|
class Pactl
|
||||||
|
{
|
||||||
|
public static function call($command, array $args=[])
|
||||||
|
{
|
||||||
|
// assemble command lin
|
||||||
|
$cmdl = array_merge([ $command ], $args);
|
||||||
|
$cmdl = join(" ", array_map("escapeshellarg", $cmdl));
|
||||||
|
|
||||||
|
echo "$ pactl {$cmdl}\n";
|
||||||
|
|
||||||
|
// call pacmd
|
||||||
|
exec("pactl {$cmdl}", $output, $retval);
|
||||||
|
|
||||||
|
// handle errors
|
||||||
|
if ($retval != 0) {
|
||||||
|
throw new \RuntimeException("Failed to call pacmd. exitcode={$retval}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// return output
|
||||||
|
if (count($output)>0) {
|
||||||
|
return $output[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,8 +26,9 @@ class PropertyList implements ArrayAccess, IteratorAggregate, Countable
|
|||||||
|
|
||||||
public function offsetGet($key)
|
public function offsetGet($key)
|
||||||
{
|
{
|
||||||
if (!array_key_exist($key, $this->properties)) {
|
if (!array_key_exists($key, $this->properties)) {
|
||||||
throw new InvalidArgumentException("No such property: {$key}");
|
return null;
|
||||||
|
// throw new InvalidArgumentException("No such property: {$key}");
|
||||||
}
|
}
|
||||||
return $this->properties[$key];
|
return $this->properties[$key];
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ namespace NoccyLabs\PulseAudio;
|
|||||||
use NoccyLabs\PulseAudio\Module\ModuleList;
|
use NoccyLabs\PulseAudio\Module\ModuleList;
|
||||||
use NoccyLabs\PulseAudio\Sink\SinkList;
|
use NoccyLabs\PulseAudio\Sink\SinkList;
|
||||||
use NoccyLabs\PulseAudio\Sink\SinkInputList;
|
use NoccyLabs\PulseAudio\Sink\SinkInputList;
|
||||||
|
use NoccyLabs\PulseAudio\Sink\NullSink;
|
||||||
use NoccyLabs\PulseAudio\Source\SourceList;
|
use NoccyLabs\PulseAudio\Source\SourceList;
|
||||||
use NoccyLabs\PulseAudio\Source\SourceOutputList;
|
use NoccyLabs\PulseAudio\Source\SourceOutputList;
|
||||||
use NoccyLabs\PulseAudio\Client\ClientList;
|
use NoccyLabs\PulseAudio\Client\ClientList;
|
||||||
@ -19,37 +20,54 @@ class PulseAudio
|
|||||||
*/
|
*/
|
||||||
public function getModules()
|
public function getModules()
|
||||||
{
|
{
|
||||||
return new ModuleList();
|
return new ModuleList($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSinks()
|
public function getSinks()
|
||||||
{
|
{
|
||||||
return new SinkList();
|
return new SinkList($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createNullSink($name=null)
|
||||||
|
{
|
||||||
|
return new NullSink($this, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSinkByIndex($index)
|
||||||
|
{
|
||||||
|
$sinks = $this->getSinks();
|
||||||
|
return $sinks[$index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSinkInputs()
|
public function getSinkInputs()
|
||||||
{
|
{
|
||||||
return new SinkInputList();
|
return new SinkInputList($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSources()
|
public function getSources()
|
||||||
{
|
{
|
||||||
return new SourceList();
|
return new SourceList($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSourceOutputs()
|
public function getSourceOutputs()
|
||||||
{
|
{
|
||||||
return new SourceOutputList();
|
return new SourceOutputList($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getClients()
|
public function getClients()
|
||||||
{
|
{
|
||||||
return new ClientList();
|
return new ClientList($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClientByIndex($index)
|
||||||
|
{
|
||||||
|
$clients = $this->getClients();
|
||||||
|
return $clients[$index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCards()
|
public function getCards()
|
||||||
{
|
{
|
||||||
return new CardList();
|
return new CardList($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
53
src/Sink/NullSink.php
Normal file
53
src/Sink/NullSink.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace NoccyLabs\PulseAudio\Sink;
|
||||||
|
|
||||||
|
use NoccyLabs\PulseAudio\Helper\Pactl;
|
||||||
|
use NoccyLabs\PulseAudio\Helper\Pacmd;
|
||||||
|
use NoccyLabs\PulseAudio\PulseAudio;
|
||||||
|
use NoccyLabs\PulseAudio\PropertyList;
|
||||||
|
|
||||||
|
class NullSink extends Sink
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $destroyed = false;
|
||||||
|
|
||||||
|
protected $moduleIndex;
|
||||||
|
|
||||||
|
public function __construct(PulseAudio $pulse, $name=null)
|
||||||
|
{
|
||||||
|
$name = $name?:uniqid("null");
|
||||||
|
|
||||||
|
$this->moduleIndex = Pactl::call('load-module', [ 'module-null-sink', 'sink_name='.$name ]);
|
||||||
|
|
||||||
|
$sinks = Pacmd::query('list-sinks');
|
||||||
|
foreach ($sinks as $index=>$sink) {
|
||||||
|
if ($sink['name'] == $name) {
|
||||||
|
parent::__construct($pulse, $index, $sink);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \RuntimeException("Unable to create null sink!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
if (!$this->isDestroyed()) {
|
||||||
|
$this->destroySink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroySink()
|
||||||
|
{
|
||||||
|
Pactl::call('unload-module', [ $this->moduleIndex ]);
|
||||||
|
$this->destroyed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isDestroyed()
|
||||||
|
{
|
||||||
|
return $this->destroyed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace NoccyLabs\PulseAudio\Sink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record from a PulseAudio sink
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Recorder
|
||||||
|
{
|
||||||
|
/** @const The number of seconds to wait for parec to exit */
|
||||||
|
const STOP_TIMEOUT = 5;
|
||||||
|
/** @var Sink The sink to record from */
|
||||||
|
protected $sink;
|
||||||
|
/** @var resource The process handle of parec */
|
||||||
|
protected $proc;
|
||||||
|
/** @var array|null The pipes of the sink */
|
||||||
|
protected $pipes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param Sink $sink The sink to record from
|
||||||
|
*/
|
||||||
|
public function __construct(Sink $sink)
|
||||||
|
{
|
||||||
|
$this->sink = $sink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the filename to write to
|
||||||
|
*
|
||||||
|
* @param string $filename
|
||||||
|
*/
|
||||||
|
public function setFilename($filename)
|
||||||
|
{
|
||||||
|
$this->filename = $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start recording.
|
||||||
|
*
|
||||||
|
* @return bool True if started, false if a capture is already running
|
||||||
|
*/
|
||||||
|
public function start()
|
||||||
|
{
|
||||||
|
// Don't do anything if we are already recording'
|
||||||
|
if ($this->proc) {
|
||||||
|
$status = proc_get_status($this->proc);
|
||||||
|
if ($status['running']==true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
proc_close($this->proc);
|
||||||
|
}
|
||||||
|
// Otherwise start recording
|
||||||
|
$cmdl = sprintf(
|
||||||
|
"parecord --format=s16le --file-format=wav --monitor-stream %d",
|
||||||
|
$this->sink->getMonitorIndex()
|
||||||
|
);
|
||||||
|
|
||||||
|
$filename = $this->filename?:"output.wav";
|
||||||
|
|
||||||
|
echo "$ {$cmdl}\n";
|
||||||
|
|
||||||
|
$ds = [
|
||||||
|
0 => STDIN,
|
||||||
|
1 => fopen($filename,'wb'),
|
||||||
|
2 => STDERR
|
||||||
|
];
|
||||||
|
$this->proc = proc_open($cmdl, $ds, $pipes);
|
||||||
|
$this->pipes = $pipes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop recording.
|
||||||
|
*
|
||||||
|
* @return bool True if not capturing or capture stopped ok
|
||||||
|
*/
|
||||||
|
public function stop()
|
||||||
|
{
|
||||||
|
if (!$this->proc) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a SIGINT to parec
|
||||||
|
proc_terminate($this->proc, 2);
|
||||||
|
|
||||||
|
// Wait for parec to close
|
||||||
|
$expire = microtime(true)+self::STOP_TIMEOUT;
|
||||||
|
$this->pipes = null;
|
||||||
|
do {
|
||||||
|
$status = proc_get_status($this->proc);
|
||||||
|
usleep(10000);
|
||||||
|
} while ($status['running'] && (microtime(true)<$expire));
|
||||||
|
|
||||||
|
// Return status; if running return false
|
||||||
|
return !$status['running'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace NoccyLabs\PulseAudio\Sink;
|
namespace NoccyLabs\PulseAudio\Sink;
|
||||||
|
|
||||||
|
use NoccyLabs\PulseAudio\PulseAudio;
|
||||||
use NoccyLabs\PulseAudio\PropertyList;
|
use NoccyLabs\PulseAudio\PropertyList;
|
||||||
|
|
||||||
class Sink
|
class Sink
|
||||||
@ -17,12 +18,18 @@ class Sink
|
|||||||
|
|
||||||
protected $properties;
|
protected $properties;
|
||||||
|
|
||||||
public function __construct($index, array $sink)
|
protected $pulse;
|
||||||
|
|
||||||
|
protected $monitor;
|
||||||
|
|
||||||
|
public function __construct(PulseAudio $pulse, $index, array $sink)
|
||||||
{
|
{
|
||||||
|
$this->pulse = $pulse;
|
||||||
$this->index = $index;
|
$this->index = $index;
|
||||||
$this->name = $sink['name'];
|
$this->name = $sink['name'];
|
||||||
$this->card = $sink['card'];
|
//$this->card = $sink['card'];
|
||||||
$this->driver = $sink['driver'];
|
$this->driver = $sink['driver'];
|
||||||
|
$this->monitor = $sink['monitor source'];
|
||||||
$this->properties = new PropertyList($sink['properties'], true);
|
$this->properties = new PropertyList($sink['properties'], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,10 +58,20 @@ class Sink
|
|||||||
return $this->driver;
|
return $this->driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMonitorIndex()
|
||||||
|
{
|
||||||
|
return $this->monitor;
|
||||||
|
}
|
||||||
|
|
||||||
public function moveToSink(Sink $sink)
|
public function moveToSink(Sink $sink)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function createRecorder()
|
||||||
|
{
|
||||||
|
return new Recorder($this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace NoccyLabs\PulseAudio\Sink;
|
namespace NoccyLabs\PulseAudio\Sink;
|
||||||
|
|
||||||
|
use NoccyLabs\PulseAudio\Helper\Pactl;
|
||||||
|
use NoccyLabs\PulseAudio\PulseAudio;
|
||||||
use NoccyLabs\PulseAudio\PropertyList;
|
use NoccyLabs\PulseAudio\PropertyList;
|
||||||
|
|
||||||
class SinkInput
|
class SinkInput
|
||||||
@ -15,7 +17,9 @@ class SinkInput
|
|||||||
|
|
||||||
protected $properties;
|
protected $properties;
|
||||||
|
|
||||||
public function __construct($index, array $input=[])
|
protected $pulse;
|
||||||
|
|
||||||
|
public function __construct(PulseAudio $pulse, $index, array $input=[])
|
||||||
{
|
{
|
||||||
$this->index = $index;
|
$this->index = $index;
|
||||||
$this->sink = $input['sink'];
|
$this->sink = $input['sink'];
|
||||||
@ -38,9 +42,14 @@ class SinkInput
|
|||||||
return $this->client;
|
return $this->client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getProperty($key)
|
||||||
|
{
|
||||||
|
return $this->properties[$key];
|
||||||
|
}
|
||||||
|
|
||||||
public function moveToSink(Sink $sink)
|
public function moveToSink(Sink $sink)
|
||||||
{
|
{
|
||||||
|
Pactl::call('move-sink-input', [ $this->index, $sink->getName() ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace NoccyLabs\PulseAudio\Sink;
|
namespace NoccyLabs\PulseAudio\Sink;
|
||||||
|
|
||||||
|
use NoccyLabs\PulseAudio\PulseAudio;
|
||||||
use NoccyLabs\PulseAudio\Helper\Pacmd;
|
use NoccyLabs\PulseAudio\Helper\Pacmd;
|
||||||
use ArrayAccess;
|
use ArrayAccess;
|
||||||
use ArrayIterator;
|
use ArrayIterator;
|
||||||
@ -12,11 +13,14 @@ class SinkInputList implements ArrayAccess, IteratorAggregate, Countable
|
|||||||
{
|
{
|
||||||
protected $inputs = [];
|
protected $inputs = [];
|
||||||
|
|
||||||
public function __construct()
|
protected $pulse;
|
||||||
|
|
||||||
|
public function __construct(PulseAudio $pulse)
|
||||||
{
|
{
|
||||||
|
$this->pulse = $pulse;
|
||||||
$inputs = Pacmd::query("list-sink-inputs");
|
$inputs = Pacmd::query("list-sink-inputs");
|
||||||
foreach ($inputs as $index=>$input) {
|
foreach ($inputs as $index=>$input) {
|
||||||
$this->inputs[] = new SinkInput($index, $input);
|
$this->inputs[] = new SinkInput($pulse, $index, $input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +40,7 @@ class SinkInputList implements ArrayAccess, IteratorAggregate, Countable
|
|||||||
public function offsetGet($key)
|
public function offsetGet($key)
|
||||||
{
|
{
|
||||||
foreach ($this->inputs as $input) {
|
foreach ($this->inputs as $input) {
|
||||||
if ($input->getIndex() == $key) {
|
if (($input->getIndex() == $key) || ($input->getName()==$key)) {
|
||||||
return $input;
|
return $input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace NoccyLabs\PulseAudio\Sink;
|
namespace NoccyLabs\PulseAudio\Sink;
|
||||||
|
|
||||||
|
use NoccyLabs\PulseAudio\PulseAudio;
|
||||||
use NoccyLabs\PulseAudio\Helper\Pacmd;
|
use NoccyLabs\PulseAudio\Helper\Pacmd;
|
||||||
use ArrayAccess;
|
use ArrayAccess;
|
||||||
use IteratorAggregate;
|
use IteratorAggregate;
|
||||||
@ -12,15 +13,23 @@ class SinkList implements ArrayAccess, IteratorAggregate, Countable
|
|||||||
{
|
{
|
||||||
protected $sinks = [];
|
protected $sinks = [];
|
||||||
|
|
||||||
public function __construct()
|
protected $pulse;
|
||||||
|
|
||||||
|
public function __construct(PulseAudio $pulse)
|
||||||
{
|
{
|
||||||
|
$this->pulse = $pulse;
|
||||||
$sinks = Pacmd::query("list-sinks");
|
$sinks = Pacmd::query("list-sinks");
|
||||||
foreach ($sinks as $index=>$sink) {
|
foreach ($sinks as $index=>$sink) {
|
||||||
$this->sinks[] = new Sink($index, $sink);
|
$this->sinks[] = new Sink($pulse, $index, $sink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createSink($name)
|
public function createNullSink($name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroyNullSink(Sink $sink)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user