cmus-bt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +57 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +26 -0
- data/bin/cmus-bt +80 -0
- data/cmus-bt.gemspec +44 -0
- data/lib/cmus-bt/device.rb +11 -0
- data/lib/cmus-bt/device/bluetooth.rb +64 -0
- data/lib/cmus-bt/device/input.rb +106 -0
- data/lib/cmus-bt/main.rb +88 -0
- data/lib/cmus-bt/player.rb +128 -0
- data/lib/cmus-bt/version.rb +3 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 40f75a07520ceab5bd721323a216a5bf0f846e27c3068de91b53823ed13c2c13
|
4
|
+
data.tar.gz: 8efa1239b84969b51c5e82267ebdcf3ade22fcbd35d5824b243ccd7524836433
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 49d59dcc858a9501e11506a15148b064b1bec027add482a0b110c4fb56920bb39c2a3593ccb6ff95fdc87aacb0c2a9d57c1c470a23dbdaf120b5e0fdb5e1f63a
|
7
|
+
data.tar.gz: 36ca6db14d83743669db3d858cab55a6c58b560db8ee110aaa8fff2699c01ee733dee6f76ed13ac46b274e04ec83962c2020e78eb26aa156b9f0c25d86ac5602
|
data/.gitignore
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
# Used by dotenv library to load environment variables.
|
14
|
+
# .env
|
15
|
+
|
16
|
+
# Ignore Byebug command history file.
|
17
|
+
.byebug_history
|
18
|
+
|
19
|
+
## Specific to RubyMotion:
|
20
|
+
.dat*
|
21
|
+
.repl_history
|
22
|
+
build/
|
23
|
+
*.bridgesupport
|
24
|
+
build-iPhoneOS/
|
25
|
+
build-iPhoneSimulator/
|
26
|
+
|
27
|
+
## Specific to RubyMotion (use of CocoaPods):
|
28
|
+
#
|
29
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
30
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
31
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
32
|
+
#
|
33
|
+
# vendor/Pods/
|
34
|
+
|
35
|
+
## Documentation cache and generated files:
|
36
|
+
/.yardoc/
|
37
|
+
/_yardoc/
|
38
|
+
/doc/
|
39
|
+
/rdoc/
|
40
|
+
|
41
|
+
## Environment normalization:
|
42
|
+
/.bundle/
|
43
|
+
/vendor/bundle
|
44
|
+
/lib/bundler/man/
|
45
|
+
|
46
|
+
# for a library or gem, you might want to ignore these files since the code is
|
47
|
+
# intended to run in multiple environments; otherwise, check them in:
|
48
|
+
Gemfile.lock
|
49
|
+
.ruby-version
|
50
|
+
.ruby-gemset
|
51
|
+
.rbenv-gemsets
|
52
|
+
|
53
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
54
|
+
.rvmrc
|
55
|
+
|
56
|
+
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
57
|
+
# .rubocop-https?--*
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Hiroshi Kuwagata
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# cmus-bt
|
2
|
+
Bluetooth AVRCP wrapper for [cmus](https://cmus.github.io/).
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
```
|
6
|
+
cmus-bt [options] {NAME|DEVICE-ADDRESS}
|
7
|
+
|
8
|
+
options:
|
9
|
+
-l, --list-available-device
|
10
|
+
--log-file=FILE
|
11
|
+
--log-level=FLEVEL
|
12
|
+
```
|
13
|
+
|
14
|
+
### options
|
15
|
+
<dl>
|
16
|
+
<dt>-l, --list-available-device</dt>
|
17
|
+
<dd>show available device list</dd>
|
18
|
+
</dl>
|
19
|
+
|
20
|
+
|
21
|
+
## Contributing
|
22
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/kwgt/cmus-bt.
|
23
|
+
|
24
|
+
## License
|
25
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
26
|
+
|
data/bin/cmus-bt
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#
|
5
|
+
# Bluetooth AVRCP wrapper for cmus.
|
6
|
+
#
|
7
|
+
# Copyright (C) 2020 Hiroshi Kuwagata <kgt9221@gmail.com>
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'optparse'
|
11
|
+
require 'pathname'
|
12
|
+
require 'pp'
|
13
|
+
|
14
|
+
#
|
15
|
+
# パッケージ内で参照する定数の定義
|
16
|
+
#
|
17
|
+
|
18
|
+
TRADITIONAL_NAME = "Bluetooth AVRCP wrapper for cmus"
|
19
|
+
APP_NAME = "cmus-bt"
|
20
|
+
|
21
|
+
BASE_DIR = Pathname.new(__FILE__).expand_path.dirname.parent
|
22
|
+
LIB_DIR = BASE_DIR + "lib"
|
23
|
+
APP_LIB_DIR = LIB_DIR + APP_NAME
|
24
|
+
|
25
|
+
#
|
26
|
+
# ライブラリロードパスの差し込み
|
27
|
+
#
|
28
|
+
|
29
|
+
$LOAD_PATH.unshift(LIB_DIR)
|
30
|
+
|
31
|
+
#
|
32
|
+
# アプリケーション本体の読み込み
|
33
|
+
#
|
34
|
+
|
35
|
+
require "#{APP_LIB_DIR + "version"}"
|
36
|
+
require "#{APP_LIB_DIR + "device"}"
|
37
|
+
require "#{APP_LIB_DIR + "player"}"
|
38
|
+
require "#{APP_LIB_DIR + "main"}"
|
39
|
+
|
40
|
+
#
|
41
|
+
# コマンドラインオプションのパース
|
42
|
+
#
|
43
|
+
|
44
|
+
OptionParser.new { |opt|
|
45
|
+
opt.banner << " {NAME|ADDRESS}"
|
46
|
+
opt.version = CMusBt::VERSION
|
47
|
+
|
48
|
+
log = {
|
49
|
+
:file => "/dev/null",
|
50
|
+
:level => :INFO
|
51
|
+
}
|
52
|
+
|
53
|
+
opt.on("-l", "--list-available-device") { |name|
|
54
|
+
$mode = :list_device
|
55
|
+
}
|
56
|
+
|
57
|
+
opt.on("--log-file=FILE") { |val|
|
58
|
+
log[:file] = val
|
59
|
+
}
|
60
|
+
|
61
|
+
opt.on("--log-level=FLEVEL") { |val|
|
62
|
+
log[:level] = val.upcase.to_sym
|
63
|
+
}
|
64
|
+
|
65
|
+
opt.parse!(ARGV)
|
66
|
+
|
67
|
+
|
68
|
+
logfile = File.open(log[:file], "a")
|
69
|
+
logfile.sync = true
|
70
|
+
|
71
|
+
$mode ||= :run_app
|
72
|
+
$logger = Logger.new(log[:file],
|
73
|
+
:level => log[:level],
|
74
|
+
:datetime_format => "%Y-%m-%dT%H:%M:%S")
|
75
|
+
}
|
76
|
+
|
77
|
+
#
|
78
|
+
# アプリケーションの起動
|
79
|
+
#
|
80
|
+
CMusBt::App.start(ARGV[0])
|
data/cmus-bt.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "cmus-bt/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cmus-bt"
|
8
|
+
spec.version = CMusBt::VERSION
|
9
|
+
spec.authors = ["Hirosho Kuwagata"]
|
10
|
+
spec.email = ["kgt9221@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Bluetooth AVRCP wrapper for cmus.}
|
13
|
+
spec.description = %q{Bluetooth AVRCP wrapper for cmus.}
|
14
|
+
spec.homepage = "https://github.com/kwgt/cmus-bt"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
if spec.respond_to?(:metadata)
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
else
|
20
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
21
|
+
"public gem pushes."
|
22
|
+
end
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been
|
26
|
+
# added into git.
|
27
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
28
|
+
`git ls-files -z`.split("\x0").reject { |f|
|
29
|
+
f.match(%r{^(test|spec|features)/})
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
spec.bindir = "bin"
|
34
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
35
|
+
spec.require_paths = ["none"]
|
36
|
+
spec.extensions = %w[]
|
37
|
+
|
38
|
+
spec.required_ruby_version = ">= 2.5.0"
|
39
|
+
|
40
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
41
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
42
|
+
spec.add_dependency "ruby-dbus", "~> 0.16.0"
|
43
|
+
spec.add_dependency "systemu", "~> 2.6.5"
|
44
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#
|
5
|
+
# Bluetooth AVRCP wrapper for cmus.
|
6
|
+
#
|
7
|
+
# Copyright (C) 2020 Hiroshi Kuwagata <kgt9221@gmail.com>
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'dbus'
|
11
|
+
|
12
|
+
module CMusBt
|
13
|
+
module Device
|
14
|
+
module Bluetooth
|
15
|
+
class << self
|
16
|
+
def service
|
17
|
+
if not @service
|
18
|
+
@service = DBus.system_bus.service("org.bluez")
|
19
|
+
@service.introspect
|
20
|
+
end
|
21
|
+
|
22
|
+
return @service
|
23
|
+
end
|
24
|
+
private :service
|
25
|
+
|
26
|
+
def root
|
27
|
+
if not @root
|
28
|
+
@root = service["/"]
|
29
|
+
@root.introspect
|
30
|
+
end
|
31
|
+
|
32
|
+
return @root
|
33
|
+
end
|
34
|
+
private :root
|
35
|
+
|
36
|
+
def objman
|
37
|
+
@objman ||=
|
38
|
+
root["org.freedesktop.DBus.ObjectManager"].GetManagedObjects
|
39
|
+
|
40
|
+
return @objman
|
41
|
+
end
|
42
|
+
private :objman
|
43
|
+
|
44
|
+
def list
|
45
|
+
ret = []
|
46
|
+
|
47
|
+
objman.each { |path, hash|
|
48
|
+
next if not hash.keys.include?("org.bluez.Device1")
|
49
|
+
|
50
|
+
iface = hash["org.bluez.Device1"]
|
51
|
+
|
52
|
+
next if iface["UUIDs"].none? {|id| /^0000110e-/ =~ id}
|
53
|
+
next if not iface["Connected"]
|
54
|
+
next if not iface["ServicesResolved"]
|
55
|
+
|
56
|
+
ret << {:address => iface["Address"], :name => iface["Name"]}
|
57
|
+
}
|
58
|
+
|
59
|
+
return ret
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#
|
5
|
+
# Bluetooth AVRCP wrapper for cmus.
|
6
|
+
#
|
7
|
+
# Copyright (C) 2020 Hiroshi Kuwagata <kgt9221@gmail.com>
|
8
|
+
#
|
9
|
+
|
10
|
+
module CMusBt
|
11
|
+
module Device
|
12
|
+
module Input
|
13
|
+
class << self
|
14
|
+
def put_ident(dst, s)
|
15
|
+
h = {}
|
16
|
+
|
17
|
+
s.scan(/([[:alpha:]]+)=(\h+)/) { |key, val|
|
18
|
+
h[key.downcase.to_sym] = val.to_i
|
19
|
+
}
|
20
|
+
|
21
|
+
dst[:ident] = h
|
22
|
+
end
|
23
|
+
|
24
|
+
def put_name(dst, s)
|
25
|
+
dst[:name] = (/^Name=\"(.*)\"$/ =~ s)? $1: nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def put_phys(dst, s)
|
29
|
+
dst[:phys] = (/^Phys=(.*)$/ =~ s)? $1: nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def put_sysfs(dst, s)
|
33
|
+
dst[:sysfs] = (/^Sysfs=(.*)$/ =~ s)? $1: nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def put_uniq(dst, s)
|
37
|
+
dst[:uniq] = (/^Sysfs=(.*)$/ =~ s)? $1: nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def put_handlers(dst, s)
|
41
|
+
a = []
|
42
|
+
|
43
|
+
s.split.each { |t|
|
44
|
+
if /^event\d+$/ =~ t
|
45
|
+
dst[:dev_file] = "/dev/input/#{t}"
|
46
|
+
else
|
47
|
+
a << t
|
48
|
+
end
|
49
|
+
}
|
50
|
+
|
51
|
+
dst[:handlers] = a
|
52
|
+
end
|
53
|
+
|
54
|
+
def put_bitmap(dst, s)
|
55
|
+
h = (dst[:bitmap] || {})
|
56
|
+
|
57
|
+
if /(.+)=(.+)/ =~ s
|
58
|
+
h[$1] = $2
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def list
|
63
|
+
ret = []
|
64
|
+
|
65
|
+
File.open("/proc/bus/input/devices") { |f|
|
66
|
+
info = {}
|
67
|
+
|
68
|
+
f.each_line { |l|
|
69
|
+
case l
|
70
|
+
when /^I: (.*)$/
|
71
|
+
put_ident(info, $1)
|
72
|
+
|
73
|
+
when /^N: (.*)$/
|
74
|
+
put_name(info, $1)
|
75
|
+
|
76
|
+
when /^P: (.*)/
|
77
|
+
put_phys(info, $1)
|
78
|
+
|
79
|
+
when /^S: (.*)$/
|
80
|
+
put_sysfs(info, $1)
|
81
|
+
|
82
|
+
when /^U: (.*)$/
|
83
|
+
put_uniq(info, $1)
|
84
|
+
|
85
|
+
when /^H: Handlers=(.*)$/
|
86
|
+
put_handlers(info, $1)
|
87
|
+
|
88
|
+
when /^B: (.*)$/
|
89
|
+
put_bitmap(info, $1)
|
90
|
+
|
91
|
+
when /^\s*$/
|
92
|
+
ret << info
|
93
|
+
info = {}
|
94
|
+
next
|
95
|
+
end
|
96
|
+
}
|
97
|
+
|
98
|
+
ret << info if not info.empty?
|
99
|
+
}
|
100
|
+
|
101
|
+
return ret
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/cmus-bt/main.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#
|
5
|
+
# Bluetooth AVRCP wrapper for cmus.
|
6
|
+
#
|
7
|
+
# Copyright (C) 2020 Hiroshi Kuwagata <kgt9221@gmail.com>
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'systemu'
|
11
|
+
|
12
|
+
module CMusBt
|
13
|
+
module App
|
14
|
+
class << self
|
15
|
+
def availables
|
16
|
+
ret = []
|
17
|
+
a = Device::Bluetooth.list
|
18
|
+
b = Device::Input.list
|
19
|
+
|
20
|
+
a.each { |ai|
|
21
|
+
b.each {|bi|
|
22
|
+
if bi[:name] == ai[:address]
|
23
|
+
ret << {
|
24
|
+
:address => ai[:address],
|
25
|
+
:name => ai[:name],
|
26
|
+
:dev_file => bi[:dev_file],
|
27
|
+
}
|
28
|
+
end
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
return ret
|
33
|
+
end
|
34
|
+
private :availables
|
35
|
+
|
36
|
+
def list_device
|
37
|
+
list = availables()
|
38
|
+
|
39
|
+
if list.empty?
|
40
|
+
print("Available device is not exist.")
|
41
|
+
|
42
|
+
else
|
43
|
+
list.each { |info|
|
44
|
+
print(" %17s %s\n" % [info[:address], info[:name]])
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
private :list_device
|
49
|
+
|
50
|
+
|
51
|
+
def run_app(targ)
|
52
|
+
$logger.info("start #{APP_NAME} version #{CMusBt::VERSION}")
|
53
|
+
list = availables()
|
54
|
+
if list.empty?
|
55
|
+
raise("available device is not exist")
|
56
|
+
end
|
57
|
+
|
58
|
+
if targ
|
59
|
+
info = list.find {|inf| inf[:address] == targ || inf[:name] == targ}
|
60
|
+
raise("specified device is not connected") if not info
|
61
|
+
else
|
62
|
+
info = list.first
|
63
|
+
end
|
64
|
+
|
65
|
+
thread = Thread.fork {Player.daemon(info)}
|
66
|
+
status = system("cmus")
|
67
|
+
|
68
|
+
thread.raise
|
69
|
+
$logger.info("exit #{APP_NAME}")
|
70
|
+
exit(status)
|
71
|
+
end
|
72
|
+
private :run_app
|
73
|
+
|
74
|
+
def start(info)
|
75
|
+
case $mode
|
76
|
+
when :list_device
|
77
|
+
list_device
|
78
|
+
|
79
|
+
when :run_app
|
80
|
+
run_app(info)
|
81
|
+
|
82
|
+
else
|
83
|
+
raise("Not implement yet")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#
|
5
|
+
# Bluetooth AVRCP wrapper for cmus.
|
6
|
+
#
|
7
|
+
# Copyright (C) 2020 Hiroshi Kuwagata <kgt9221@gmail.com>
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'systemu'
|
11
|
+
|
12
|
+
module CMusBt
|
13
|
+
module Player
|
14
|
+
# from struct input_event on <linux/event.h>
|
15
|
+
EVENT_STRUCTURE = "l!l!S!S!i!"
|
16
|
+
|
17
|
+
FUNC_TABLE = {
|
18
|
+
200 => :do_play, # KEY_PLAYCD
|
19
|
+
201 => :do_pause, # KEY_PAUSECD
|
20
|
+
163 => :do_next, # KEY_NEXTSONG
|
21
|
+
165 => :do_prev, # KEY_PREVIOUSSONG
|
22
|
+
}
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def query
|
26
|
+
begin
|
27
|
+
status, ret = systemu("cmus-remote --query")
|
28
|
+
raise if not status.success?
|
29
|
+
|
30
|
+
rescue
|
31
|
+
sleep 0.2
|
32
|
+
retry
|
33
|
+
end
|
34
|
+
|
35
|
+
return ret
|
36
|
+
end
|
37
|
+
private :query
|
38
|
+
|
39
|
+
def status
|
40
|
+
ret = catch { |tag|
|
41
|
+
query.each_line {|l| throw tag, $1.to_sym if /^status = (.+)/ =~ l}
|
42
|
+
}
|
43
|
+
|
44
|
+
return ret
|
45
|
+
end
|
46
|
+
private :status
|
47
|
+
|
48
|
+
def read_meta
|
49
|
+
ret = {}
|
50
|
+
status = nil
|
51
|
+
|
52
|
+
query.each_line { |l|
|
53
|
+
case l
|
54
|
+
when /^status (.+)/
|
55
|
+
status = $1.to_sym
|
56
|
+
|
57
|
+
when /^file (.+)/
|
58
|
+
ret[:file] = File.basename($1)
|
59
|
+
|
60
|
+
when /^tag (.+) (.+)/
|
61
|
+
ret[$1.to_sym] = $2
|
62
|
+
end
|
63
|
+
}
|
64
|
+
|
65
|
+
ret[:name] ||= ret[:file] if status == :playing
|
66
|
+
|
67
|
+
return ret
|
68
|
+
end
|
69
|
+
private :read_meta
|
70
|
+
|
71
|
+
def do_play
|
72
|
+
if status == :playing
|
73
|
+
system("cmus-remote --pause")
|
74
|
+
$logger.info("PAUSE")
|
75
|
+
else
|
76
|
+
system("cmus-remote --play")
|
77
|
+
$logger.info("PLAY")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
private :do_play
|
81
|
+
|
82
|
+
def do_pause
|
83
|
+
system("cmus-remote --pause")
|
84
|
+
$logger.info("PAUSE")
|
85
|
+
end
|
86
|
+
private :do_pause
|
87
|
+
|
88
|
+
def do_next
|
89
|
+
system("cmus-remote --next")
|
90
|
+
$logger.info("NEXT")
|
91
|
+
end
|
92
|
+
private :do_next
|
93
|
+
|
94
|
+
def do_prev
|
95
|
+
system("cmus-remote --prev")
|
96
|
+
$logger.info("PREV")
|
97
|
+
end
|
98
|
+
private :do_prev
|
99
|
+
|
100
|
+
def daemon(info)
|
101
|
+
io = File.open(info[:dev_file], "rb")
|
102
|
+
size = [0, 0, 0, 0, 0].pack(EVENT_STRUCTURE).bytesize
|
103
|
+
|
104
|
+
until io.eof?
|
105
|
+
raw = io.read(size)
|
106
|
+
tmp = raw.unpack(EVENT_STRUCTURE)
|
107
|
+
|
108
|
+
type = tmp[2]
|
109
|
+
code = tmp[3]
|
110
|
+
val = tmp[4]
|
111
|
+
|
112
|
+
$logger.debug("push #{type}, #{code}, #{val}")
|
113
|
+
|
114
|
+
next if type != 1 or val != 0
|
115
|
+
|
116
|
+
FUNC_TABLE[code] && send(FUNC_TABLE[code])
|
117
|
+
end
|
118
|
+
|
119
|
+
rescue RuntimeError
|
120
|
+
$logger.debug("stop daemon")
|
121
|
+
|
122
|
+
ensure
|
123
|
+
io&.close
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cmus-bt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hirosho Kuwagata
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-02-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ruby-dbus
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.16.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.16.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: systemu
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.6.5
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.6.5
|
69
|
+
description: Bluetooth AVRCP wrapper for cmus.
|
70
|
+
email:
|
71
|
+
- kgt9221@gmail.com
|
72
|
+
executables:
|
73
|
+
- cmus-bt
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- bin/cmus-bt
|
82
|
+
- cmus-bt.gemspec
|
83
|
+
- lib/cmus-bt/device.rb
|
84
|
+
- lib/cmus-bt/device/bluetooth.rb
|
85
|
+
- lib/cmus-bt/device/input.rb
|
86
|
+
- lib/cmus-bt/main.rb
|
87
|
+
- lib/cmus-bt/player.rb
|
88
|
+
- lib/cmus-bt/version.rb
|
89
|
+
- pkg/.gitkeep
|
90
|
+
homepage: https://github.com/kwgt/cmus-bt
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata:
|
94
|
+
homepage_uri: https://github.com/kwgt/cmus-bt
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- none
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 2.5.0
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubygems_version: 3.1.2
|
111
|
+
signing_key:
|
112
|
+
specification_version: 4
|
113
|
+
summary: Bluetooth AVRCP wrapper for cmus.
|
114
|
+
test_files: []
|