rbtune 1.0.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5e280b91c967fad699e9d8741a7ad90721431d592b26fd1a838c224cb1c0f94
4
- data.tar.gz: b68ed39a2b494f2af7f6626e3d30959917a64a43d8c2b4a6e888bbca338b3333
3
+ metadata.gz: dc6b260518a675da6cb704c192d656e93f9e072e073f4a5f23b1d05274d010c0
4
+ data.tar.gz: 4ce90d7c6f6043a80d8e915d1f39e42f7381b3a8f2506cfef36552e1a847eadb
5
5
  SHA512:
6
- metadata.gz: d6de553a844e73b388e26284e51d157c01ac931802e043158a621c943f7ceedadcced7d6c59cb1d69098f4d1aec84f22c5160d2c4159ec36789da24dbf981189
7
- data.tar.gz: b5769b820fc79b85bc4f3fe7c8d4ec12829a0deb86963fecc036d2e8d84304dc91f3052e38b068469d722d6236f6a5cb1aa84d1f765741e839258cc937f9aa25
6
+ metadata.gz: c84c1ce4737dd272ca77f89724a31bb45d4861ab5efcda5887f305940a87192b92de52234f95388bb43d95f62ac8743c0334b1fb94418e19865a37fb7eefc7cc
7
+ data.tar.gz: ce82be9a5d93bd0bbb017403ab68c9345d1d1891f8724c81e5ed1aee788f652e7673eb0224a708d6ede28b41271fffc57707ffbafc10602fb2fbc646925d6c29
data/exe/timefree CHANGED
@@ -86,7 +86,7 @@ sec = min*60
86
86
  begin
87
87
  radio = TimeFree.new
88
88
  radio.outdir = ENV['RADIODIR'] || '.'
89
- if radio_class.is_a? RadikoPremium
89
+ if radio.is_a? RadikoPremium
90
90
  account, password = kc.account
91
91
  radio.login account, password
92
92
  end
data/lib/player/ffmpeg.rb CHANGED
@@ -4,7 +4,8 @@ require "open3"
4
4
  require "player/mplayer"
5
5
 
6
6
  class FFMpeg < Player
7
- def initialize
7
+ def initialize(hash={})
8
+ self.merge! hash
8
9
  self['loglevel'] = 'warning'
9
10
  self['n'] = '' # do not overwrite
10
11
  @mplayer = Mplayer.new('-')
@@ -28,7 +29,7 @@ class FFMpeg < Player
28
29
 
29
30
  def play
30
31
  self['f'] = 'mpegts'
31
- @output = 'pipe:1'
32
+ @output = '-'
32
33
  cmd = "#{to_s} | #{@mplayer}"
33
34
  $stderr.puts 'play: '+cmd
34
35
  `#{cmd}`
@@ -39,12 +40,12 @@ class FFMpeg < Player
39
40
  def rec(file, sec, quiet = true)
40
41
  self['t'] = sec if sec
41
42
  if quiet
42
- @output = file
43
+ @output = %Q("#{file}")
43
44
  cmd = to_s
44
45
  else
45
46
  self['f'] = 'mpegts'
46
- @output = 'pipe:1'
47
- cmd = "#{to_s} | tee #{file} | #{@mplayer}"
47
+ @output = '-'
48
+ cmd = %Q(#{to_s} | tee "#{file}" | #{@mplayer})
48
49
  end
49
50
 
50
51
  puts "rec: #{cmd}"
@@ -37,7 +37,7 @@ class Mplayer < Player
37
37
 
38
38
  def rec(file, sec, quiet = true)
39
39
  self['dumpstream'] = ''
40
- self['dumpfile'] = file
40
+ self['dumpfile'] = %Q("#{file}")
41
41
  if quiet
42
42
  self['nosound'] = '' # 音声を再生しない
43
43
  end
@@ -16,7 +16,7 @@ class RtmpDump < Player
16
16
 
17
17
  def play
18
18
  # puts "play: #{to_s} | mplayer -"
19
- `#{to_s} | mplayer -`
19
+ %x(#{to_s} | mplayer -)
20
20
  end
21
21
 
22
22
 
@@ -24,12 +24,12 @@ class RtmpDump < Player
24
24
  self['stop'] = sec
25
25
 
26
26
  if quiet
27
- self['flv'] = file
27
+ self['flv'] = %Q("#{file}")
28
28
  puts "rec: #{to_s}"
29
- `#{to_s}`
29
+ %x(#{to_s})
30
30
  else
31
31
  puts "rec: #{to_s}"
32
- `#{to_s} | tee #{file} | mplayer -`
32
+ %x(#{to_s} | tee "#{file}" | mplayer -)
33
33
  end
34
34
  end
35
35
 
data/lib/rbtune/agqr.rb CHANGED
@@ -1,36 +1,15 @@
1
1
  # 文化放送 超A&G+ を受信する
2
2
 
3
3
  require "rbtune/radio"
4
- require "player/rtmpdump"
5
- require "player/ffmpeg"
6
- require "fileutils"
7
4
 
8
5
  class Agqr < Radio
9
6
  def initialize
10
- @ext = 'flv'
11
- @out_ext = 'm4a'
7
+ @ext = 'm4a'
12
8
  end
13
9
 
14
10
  def fetch_stations
15
- uri = "rtmp://fms-base1.mitene.ad.jp/agqr/aandg1"
11
+ uri = 'https://fms2.uniqueradio.jp/agqr10/aandg1.m3u8'
16
12
  [Station.new('AGQR', uri, name: '超A&G+', ascii_name: 'aandg1')]
17
13
  end
18
14
 
19
-
20
- def create_player(uri)
21
- rtmpdump = RtmpDump.new
22
- rtmpdump['rtmp'] = uri
23
- rtmpdump
24
- end
25
-
26
-
27
- def convert(tmpfile, recfile)
28
- ffmpeg = FFMpeg.new
29
- ffmpeg['loglevel'] = 'quiet'
30
- ffmpeg['i'] = %Q("#{tmpfile}")
31
- ffmpeg['acodec'] = 'copy'
32
- stdout, stderr, status = ffmpeg.rec recfile, nil
33
- FileUtils.rm tmpfile if status.success?
34
- end
35
-
36
15
  end
data/lib/rbtune/jcba.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  JCBAサイマルラジオを受信する
4
4
  =end
5
5
  require "rbtune/listenradio"
6
- require "rbtune/station"
7
6
 
8
7
 
9
8
  class Jcba < ListenRadio
@@ -5,7 +5,6 @@
5
5
 
6
6
 
7
7
  require "rbtune/radio"
8
- require "player/ffmpeg"
9
8
  require "json"
10
9
 
11
10
 
@@ -16,13 +15,6 @@ class ListenRadio < Radio
16
15
  @ext = 'mp4'
17
16
  end
18
17
 
19
- def create_player(uri)
20
- player = FFMpeg.new
21
- player['i'] = uri # input stream
22
- player['acodec'] = 'copy' # acodecオプションはiオプションのあとに置かないとエラー
23
- player
24
- end
25
-
26
18
 
27
19
  def stations_uri
28
20
  'http://listenradio.jp/service/channel.aspx'
data/lib/rbtune/radiko.rb CHANGED
@@ -1,84 +1,56 @@
1
1
  #radiko.rb
2
2
  # coding: utf-8
3
3
 
4
- require "mechanize"
5
4
  require "rbtune/radio"
6
- require "player/rtmpdump"
7
- require 'swf_ruby'
8
5
 
9
6
 
10
7
  class Radiko < Radio
11
8
  attr_reader :authtoken
12
9
 
13
10
 
14
- def playerurl
15
- "http://radiko.jp/apps/js/flash/myplayer-release.swf"
16
- end
17
-
18
-
19
- def playerfile
20
- "player.swf"
21
- end
22
-
23
-
24
- def keyfile
25
- "authkey.png"
26
- end
27
-
28
-
29
11
  # get_auth2 の返り値により @area_id, @area_ja, @area_en が設定される
30
12
  def open
31
- unless File.exists? playerfile
32
- $stderr.puts 'fetching player...'
33
- fetch_file playerurl, playerfile
34
- end
35
- unless File.exists? keyfile
36
- swfextract playerfile, 12, keyfile
37
- end
38
-
39
- @authtoken, partialkey = authenticate1 'https://radiko.jp/v2/api/auth1_fms'
40
- @area_id, @area_ja, @area_en = authenticate2 'https://radiko.jp/v2/api/auth2_fms', authtoken, partialkey
13
+ @authtoken, partialkey = authenticate1 'https://radiko.jp/v2/api/auth1'
14
+ @area_id, @area_ja, @area_en = authenticate2 'https://radiko.jp/v2/api/auth2', authtoken, partialkey
41
15
  puts "area: #{area_id} (#{area_ja}: #{area_en})"
42
16
  end
43
17
 
44
18
 
45
19
  def channel_to_uri
46
- xml = agent.get "http://radiko.jp/v2/station/stream/#{@channel}.xml"
47
- xml.at('//url/item').text
20
+ uri = "http://radiko.jp/v2/station/stream_smh_multi/#{@channel}.xml"
21
+ xml = agent.get uri
22
+ xml.at('//url/playlist_create_url').text
48
23
  end
49
24
 
50
25
 
51
26
  def create_player(uri)
52
- rtmpdump = RtmpDump.new
53
- rtmpdump['rtmp'] = uri
54
- rtmpdump['swfVfy'] = playerurl
55
- rtmpdump['conn'] = %Q(S:"" --conn S:"" --conn S:"" --conn S:#{authtoken})
56
- rtmpdump
27
+ FFMpeg.new( {
28
+ headers: %Q("X-Radiko-Authtoken: #{authtoken}"),
29
+ i: %Q("#{uri}"),
30
+ # acodec: 'copy', # acodecオプションはiオプションのあとに置かないとエラー
31
+ } )
57
32
  end
58
33
 
59
34
 
60
35
  def authenticate1(url)
61
- res = agent.post url, {}, {
62
- 'pragma' => 'no-cache',
63
- 'X-Radiko-App' => 'pc_ts',
64
- 'X-Radiko-App-Version' => '4.0.0',
65
- 'X-Radiko-User' => 'test-stream',
36
+ agent.request_headers = {
37
+ 'X-Radiko-App' => 'pc_html5',
38
+ 'X-Radiko-App-Version' => '0.0.1',
66
39
  'X-Radiko-Device' => 'pc',
40
+ 'X-Radiko-User' => 'dummy_user',
67
41
  }
68
- s = res.body
69
- s.sub! /\r\n\r\n.*/m, ''
70
- arr = s.split(/\r\n/).map{|s| s.split('=')}.flatten
71
- auth1 = Hash[*arr]
72
- authtoken = auth1['X-Radiko-AuthToken'] || auth1['X-RADIKO-AUTHTOKEN']
73
- offset = auth1['X-Radiko-KeyOffset'].to_i
74
- length = auth1['X-Radiko-KeyLength'].to_i
75
- partialkey = read_partialkey keyfile, offset, length
42
+ res = agent.get url
43
+ auth1 = res.response
44
+ authtoken = auth1['x-radiko-authtoken']
45
+ offset = auth1['x-radiko-keyoffset'].to_i
46
+ length = auth1['x-radiko-keylength'].to_i
47
+ partialkey = read_partialkey offset, length
76
48
  [authtoken, partialkey]
77
49
  end
78
50
 
79
51
 
80
- def read_partialkey(file, offset, length)
81
- key = File.open(file, "rb") { |io| io.read(offset + length) }
52
+ def read_partialkey(offset, length)
53
+ key = "bcd151073c03b352e1ef2fd66c32209da9ca0afa"
82
54
  Base64.encode64(key[offset,length]).chomp
83
55
  end
84
56
 
@@ -87,15 +59,13 @@ class Radiko < Radio
87
59
  def authenticate2(url, authtoken, partialkey)
88
60
  # pp [url, authtoken, partialkey]
89
61
  agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
90
- res = agent.post url, {}, {
91
- 'pragma' => 'no-cache',
92
- 'X-Radiko-App' => 'pc_ts',
93
- 'X-Radiko-App-Version' => '4.0.0',
94
- 'X-Radiko-User' => 'test-stream',
62
+ agent.request_headers = {
95
63
  'X-Radiko-Device' => 'pc',
64
+ 'X-Radiko-User' => 'dummy_user',
96
65
  'X-Radiko-Authtoken' => authtoken,
97
66
  'X-Radiko-Partialkey' => partialkey,
98
67
  }
68
+ res = agent.get url
99
69
  body = res.body
100
70
  body.force_encoding 'utf-8'
101
71
  body.split(',').map(&:strip)
@@ -119,25 +89,4 @@ class Radiko < Radio
119
89
  end
120
90
 
121
91
 
122
- def fetch_file(url, file=nil)
123
- content = agent.get_file(url)
124
- File.open(file, "wb") { |fout| fout.write content } if file
125
- content
126
- end
127
-
128
-
129
- def swfextract(swffile, character_id, out_file)
130
- swf = SwfRuby::SwfDumper.new
131
- swf.open(swffile)
132
- swf.tags.each_with_index do |tag, i|
133
- tag = swf.tags[i]
134
- if tag.character_id && tag.character_id == character_id
135
- offset = swf.tags_addresses[i]
136
- len = tag.length
137
- File.open(out_file, 'wb') { |out| out.print tag.data[6..-1] }
138
- break
139
- end
140
- end
141
- end
142
-
143
92
  end
data/lib/rbtune/radio.rb CHANGED
@@ -10,7 +10,9 @@
10
10
  require "date"
11
11
  require "benchmark"
12
12
  require "net/http"
13
- require "rexml/document"
13
+ require "mechanize"
14
+ require "player/ffmpeg"
15
+ require "rbtune/station"
14
16
 
15
17
  class Radio
16
18
  attr_accessor :outdir
@@ -88,7 +90,11 @@ class Radio
88
90
 
89
91
 
90
92
  def create_player(uri)
91
- # rtmpdumpのコマンドラインを生成する(playから呼ばれる)
93
+ # Player のサブクラスのインスタンスを生成する
94
+ FFMpeg.new( {
95
+ i: uri,
96
+ # acodec: 'copy', # acodecオプションはiオプションのあとに置かないとエラー
97
+ } )
92
98
  end
93
99
 
94
100
 
@@ -167,7 +173,7 @@ class Radio
167
173
  ffmpeg = FFMpeg.new
168
174
  ffmpeg['loglevel'] = 'quiet'
169
175
  ffmpeg['i'] = %Q("#{tmpfile}")
170
- ffmpeg['b:a'] = '70k'
176
+ # ffmpeg['b:a'] = '70k'
171
177
  stdout, stderr, status = ffmpeg.rec recfile, nil
172
178
  FileUtils.rm tmpfile if status.success?
173
179
  end
data/lib/rbtune/radiru.rb CHANGED
@@ -2,51 +2,41 @@
2
2
  # coding: utf-8
3
3
 
4
4
  require "rbtune/radio"
5
- require "player/ffmpeg"
6
- require "fileutils"
7
5
 
8
6
  class Radiru < Radio
9
7
 
10
8
 
11
- def create_player(uri)
12
- ffmpeg = FFMpeg.new
13
- ffmpeg['i'] = uri # input stream
14
- ffmpeg['acodec'] = 'copy' # acodecオプションはiオプションのあとに置かないとエラー
15
- ffmpeg
9
+ def stations_uri
10
+ "https://www.nhk.or.jp/radio/config/config_web.xml"
16
11
  end
17
12
 
18
13
 
19
- def stations_uri
20
- "https://www.nhk.or.jp/radio/config/config_web.xml"
21
- end
22
-
23
-
24
- def parse_stations(body)
25
- stations = body.search '//data'
26
- stationsjp = {
27
- 'r1' => "ラジオ第1",
28
- 'r2' => "ラジオ第2",
29
- 'fm' => "FM",
30
- }
31
- stations = stations.map do |station|
32
- areajp = station.at('areajp').text
33
- area = station.at('area').text
34
- # 地区ごとに第1, 第2, FM を登録する
35
- r1, r2, fm = %w(r1 r2 fm).map do |v|
36
- hls = "#{v}hls"
37
- id = "nhk#{v}-#{area}".upcase
38
- uri = station.at(hls).text
39
- name = "NHK#{stationsjp[v]}-#{areajp}"
40
- Station.new(id, uri, name: name, ascii_name: id)
41
- end
42
- end
43
- stations.flatten!
44
- # id: NHKR1, NHKR2, NHKFM を東京局に割り当てる 
45
- stations.find_all { |station| station.id =~ /-TOKYO/}.reverse.map do |station|
46
- id = station.id.sub(/-TOKYO/, '')
47
- stations.unshift Station.new(id, station.uri, name: station.name, ascii_name: id)
48
- end
49
- stations
50
- end
14
+ def parse_stations(body)
15
+ stations = body.search '//data'
16
+ stationsjp = {
17
+ 'r1' => "ラジオ第1",
18
+ 'r2' => "ラジオ第2",
19
+ 'fm' => "FM",
20
+ }
21
+ stations = stations.map do |station|
22
+ areajp = station.at('areajp').text
23
+ area = station.at('area').text
24
+ # 地区ごとに第1, 第2, FM を登録する
25
+ r1, r2, fm = %w(r1 r2 fm).map do |v|
26
+ hls = "#{v}hls"
27
+ id = "nhk#{v}-#{area}".upcase
28
+ uri = station.at(hls).text
29
+ name = "NHK#{stationsjp[v]}-#{areajp}"
30
+ Station.new(id, uri, name: name, ascii_name: id)
31
+ end
32
+ end
33
+ stations.flatten!
34
+ # id: NHKR1, NHKR2, NHKFM を東京局に割り当てる 
35
+ stations.find_all { |station| station.id =~ /-TOKYO/}.reverse.map do |station|
36
+ id = station.id.sub(/-TOKYO/, '')
37
+ stations.unshift Station.new(id, station.uri, name: station.name, ascii_name: id)
38
+ end
39
+ stations
40
+ end
51
41
 
52
42
  end
data/lib/rbtune/simul.rb CHANGED
@@ -2,14 +2,13 @@
2
2
 
3
3
  require "rbtune/radio"
4
4
  require "player/mplayer"
5
- require "rbtune/station"
5
+ require "rexml/document"
6
6
 
7
7
  class Simul < Radio
8
8
 
9
9
  def initialize
10
10
  super
11
11
  @ext = 'asf'
12
- @out_ext = 'm4a'
13
12
  end
14
13
 
15
14
 
@@ -44,11 +43,6 @@ class Simul < Radio
44
43
  end
45
44
 
46
45
 
47
- def convert(tmpfile, recfile)
48
- convert_ffmpeg(tmpfile, recfile)
49
- end
50
-
51
-
52
46
  def link_to_station_id(link)
53
47
  link =~ %r{(/asx/([\w-]+).asx|nkansai.tv/(\w+)/?\Z|(flower|redswave|fm-tanba|darazfm|AmamiFM|comiten|fm-shimabara|fm-kitaq))}
54
48
  id = ($2 || $3 || $4).sub(/fm[-_]/, 'fm').sub(/[-_]fm/, 'fm')
@@ -1,8 +1,5 @@
1
1
  require "rbtune/radiko_premium"
2
- require "rbtune/station"
3
- require "player/ffmpeg"
4
2
  require "date"
5
- require "fileutils"
6
3
 
7
4
  class DateTime
8
5
  def timefree
@@ -40,12 +37,9 @@ class TimeFree < RadikoPremium
40
37
  end
41
38
 
42
39
 
43
- def create_player(uri)
44
- ffmpeg = FFMpeg.new
45
- ffmpeg['loglevel'] = 'info'
46
- ffmpeg['headers'] = %Q("X-Radiko-AuthToken: #{authtoken}")
47
- ffmpeg['i'] = %Q("#{uri}")
48
- ffmpeg['acodec'] = 'copy' # acodecオプションはiオプションのあとに置かないとエラー
49
- ffmpeg
50
- end
40
+ def create_player(uri)
41
+ player = super
42
+ player['acodec'] = 'copy'
43
+ player
44
+ end
51
45
  end
@@ -1,3 +1,3 @@
1
1
  module Rbtune
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.3"
3
3
  end
data/rbtune.gemspec CHANGED
@@ -24,11 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.require_paths = ["lib"]
25
25
 
26
26
  spec.add_dependency "mechanize", "~> 2.7"
27
- spec.add_dependency "rmagick", "= 2.13.2" # swf_ruby が依存するので固定
28
- spec.add_dependency "swf_ruby", "~> 0.2"
29
27
  spec.add_dependency "pit", "~> 0.0.7"
30
28
  spec.add_development_dependency "bundler", "~> 2.1"
31
- spec.add_development_dependency "rake", "~> 10.0"
32
- # spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "rake", ">= 12.3.3"
33
30
 
34
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbtune
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - ASAHI,Michiharu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-01 00:00:00.000000000 Z
11
+ date: 2021-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mechanize
@@ -24,34 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.7'
27
- - !ruby/object:Gem::Dependency
28
- name: rmagick
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 2.13.2
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 2.13.2
41
- - !ruby/object:Gem::Dependency
42
- name: swf_ruby
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.2'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.2'
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: pit
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +56,16 @@ dependencies:
84
56
  name: rake
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
- - - "~>"
59
+ - - ">="
88
60
  - !ruby/object:Gem::Version
89
- version: '10.0'
61
+ version: 12.3.3
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
- - - "~>"
66
+ - - ">="
95
67
  - !ruby/object:Gem::Version
96
- version: '10.0'
68
+ version: 12.3.3
97
69
  description: Playing and Recording Radiko, Radiru*Radiru and the other IP simulcast
98
70
  sites.
99
71
  email: