File: pulseaudio.rb

package info (click to toggle)
mikutter 5.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,780 kB
  • sloc: ruby: 22,912; sh: 186; makefile: 21
file content (48 lines) | stat: -rw-r--r-- 1,433 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# frozen_string_literal: true

require 'shellwords'
require 'open3'

Plugin.create(:pulseaudio) do
  defsound :pulseaudio, 'PulseAudio' do |filename|
    SerialThread.new do
      if FileTest.exist?(filename)
        pacmd.puts "play-file #{Shellwords.escape(filename)} #{default_sink}"
      end
    rescue => err
      error 'Error occured. Force close connection.'
      error err
      pacmd.close
      pacmd.puts "play-file #{filename} #{default_sink}"
    end
  end

  # pacmd コマンドを実行して、書き込み用IOを返す。既に書き込み用IOが開いているならそちらを返す。
  # 既にcloseされているなら新しく接続しなおして返す。
  # ==== Return
  # IO 書き込み用のIO
  def pacmd
    if defined?(@pacmd) && !@pacmd.closed?
      @pacmd
    else
      @default_sink = nil
      @pacmd = IO.popen('pacmd', File::Constants::WRONLY).tap do |pacmd|
        pacmd.close_on_exec = true
        pacmd.autoclose = true
        pacmd.sync = true
      end
    end
  end

  # PulseAudioに設定されている Default Sinkの名前を返す
  # ==== Return
  # String デフォルトシンクの名前
  def default_sink
    @default_sink ||= Open3.popen2({'LC_ALL' => 'C'} ,'pactl info') do |input, output, _|
      input.close
      output
        .find{ |line| line.start_with?('Default Sink') }
        &.match(/^Default Sink\s*:\s*(.+)$/)&.captures&.first
    end
  end
end