rbtune 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb53e6a07b42be40307dcb57f24feb17ed93c08a205b3de65fe1e735ad4a1fb0
4
- data.tar.gz: 5b35fe944e8f9c7acdb4a24d26d360ee17e854a9c88a90c316daea160f3660f9
3
+ metadata.gz: e1f2f619e38457d2d012382678f54a2af34d07eae09af7502b4b43a68e11d07a
4
+ data.tar.gz: ba87857b776104f945d459a08cf8e197768dba41530ede82b9fc1193d501c517
5
5
  SHA512:
6
- metadata.gz: 9050ad90614df7f18238304a32fd1b65bff2953a2785b8a3e387ab56b0a3784d06d6fc9a2a07de388f431fb59b87e5faadd1f49c3bb965e2c4177e959d80d019
7
- data.tar.gz: 73d8790cca49deed1fc33b2fed141b2a40636eb62b6e0a6eb38748b6f9f731a6478515724117ef4c3ba4bd7162625fb599081a0ec0987d8b825660a3c392e1f1
6
+ metadata.gz: 1218ee9599058b710516372428646e10b86c7a411255b32140090149a036f5afb5691a91d0d57b34964dc2a3e58f5da147527d8aa373bf24815cf8488333a25c
7
+ data.tar.gz: fb3320bf9e149348f6bb45f870eba5bc17f5209758cddff2dc87181df6419b9f0fd7350a419485358fc987c069f32dc1b2d52cb3f602d1861cb8704db34803bd
@@ -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}`
@@ -43,7 +44,7 @@ class FFMpeg < Player
43
44
  cmd = to_s
44
45
  else
45
46
  self['f'] = 'mpegts'
46
- @output = 'pipe:1'
47
+ @output = '-'
47
48
  cmd = "#{to_s} | tee #{file} | #{@mplayer}"
48
49
  end
49
50
 
@@ -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
@@ -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'
@@ -3,82 +3,55 @@
3
3
 
4
4
  require "mechanize"
5
5
  require "rbtune/radio"
6
- require "player/rtmpdump"
7
- require 'swf_ruby'
8
6
 
9
7
 
10
8
  class Radiko < Radio
11
9
  attr_reader :authtoken
12
10
 
13
11
 
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
12
  # get_auth2 の返り値により @area_id, @area_ja, @area_en が設定される
30
13
  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
14
+ @authtoken, partialkey = authenticate1 'https://radiko.jp/v2/api/auth1'
15
+ @area_id, @area_ja, @area_en = authenticate2 'https://radiko.jp/v2/api/auth2', authtoken, partialkey
41
16
  puts "area: #{area_id} (#{area_ja}: #{area_en})"
42
17
  end
43
18
 
44
19
 
45
20
  def channel_to_uri
46
- xml = agent.get "http://radiko.jp/v2/station/stream/#{@channel}.xml"
47
- xml.at('//url/item').text
21
+ uri = "http://radiko.jp/v2/station/stream_smh_multi/#{@channel}.xml"
22
+ xml = agent.get uri
23
+ xml.at('//url/playlist_create_url').text
48
24
  end
49
25
 
50
26
 
51
27
  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
28
+ FFMpeg.new( {
29
+ headers: %Q("X-Radiko-Authtoken: #{authtoken}"),
30
+ i: %Q("#{uri}"),
31
+ # acodec: 'copy', # acodecオプションはiオプションのあとに置かないとエラー
32
+ } )
57
33
  end
58
34
 
59
35
 
60
36
  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',
37
+ agent.request_headers = {
38
+ 'X-Radiko-App' => 'pc_html5',
39
+ 'X-Radiko-App-Version' => '0.0.1',
66
40
  'X-Radiko-Device' => 'pc',
41
+ 'X-Radiko-User' => 'dummy_user',
67
42
  }
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
43
+ res = agent.get url
44
+ auth1 = res.response
45
+ authtoken = auth1['x-radiko-authtoken']
46
+ offset = auth1['x-radiko-keyoffset'].to_i
47
+ length = auth1['x-radiko-keylength'].to_i
48
+ partialkey = read_partialkey offset, length
76
49
  [authtoken, partialkey]
77
50
  end
78
51
 
79
52
 
80
- def read_partialkey(file, offset, length)
81
- key = File.open(file, "rb") { |io| io.read(offset + length) }
53
+ def read_partialkey(offset, length)
54
+ key = "bcd151073c03b352e1ef2fd66c32209da9ca0afa"
82
55
  Base64.encode64(key[offset,length]).chomp
83
56
  end
84
57
 
@@ -87,15 +60,13 @@ class Radiko < Radio
87
60
  def authenticate2(url, authtoken, partialkey)
88
61
  # pp [url, authtoken, partialkey]
89
62
  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',
63
+ agent.request_headers = {
95
64
  'X-Radiko-Device' => 'pc',
65
+ 'X-Radiko-User' => 'dummy_user',
96
66
  'X-Radiko-Authtoken' => authtoken,
97
67
  'X-Radiko-Partialkey' => partialkey,
98
68
  }
69
+ res = agent.get url
99
70
  body = res.body
100
71
  body.force_encoding 'utf-8'
101
72
  body.split(',').map(&:strip)
@@ -119,25 +90,4 @@ class Radiko < Radio
119
90
  end
120
91
 
121
92
 
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
93
  end
@@ -10,7 +10,8 @@
10
10
  require "date"
11
11
  require "benchmark"
12
12
  require "net/http"
13
- require "rexml/document"
13
+ require "player/ffmpeg"
14
+ require "rbtune/station"
14
15
 
15
16
  class Radio
16
17
  attr_accessor :outdir
@@ -89,6 +90,10 @@ class Radio
89
90
 
90
91
  def create_player(uri)
91
92
  # rtmpdumpのコマンドラインを生成する(playから呼ばれる)
93
+ FFMpeg.new( {
94
+ i: uri,
95
+ # acodec: 'copy', # acodecオプションはiオプションのあとに置かないとエラー
96
+ } )
92
97
  end
93
98
 
94
99
 
@@ -167,7 +172,7 @@ class Radio
167
172
  ffmpeg = FFMpeg.new
168
173
  ffmpeg['loglevel'] = 'quiet'
169
174
  ffmpeg['i'] = %Q("#{tmpfile}")
170
- ffmpeg['b:a'] = '70k'
175
+ # ffmpeg['b:a'] = '70k'
171
176
  stdout, stderr, status = ffmpeg.rec recfile, nil
172
177
  FileUtils.rm tmpfile if status.success?
173
178
  end
@@ -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
@@ -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,4 @@ 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
51
40
  end
@@ -1,3 +1,3 @@
1
1
  module Rbtune
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -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.2
4
+ version: 1.0.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: 2020-12-07 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: