irecorder 0.0.4-linux
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.
- data/MIT-LICENSE +19 -0
- data/README +37 -0
- data/Rakefile +67 -0
- data/bin/irecorder +9 -0
- data/bin/irecorder.rb +994 -0
- data/lib/bbcnet.rb +244 -0
- data/lib/download.rb +325 -0
- data/lib/logwin.rb +119 -0
- data/lib/mylibs.rb +279 -0
- data/lib/settings.rb +386 -0
- data/lib/taskwin.rb +354 -0
- data/resources/bbcstyle.qss +424 -0
- metadata +105 -0
data/lib/bbcnet.rb
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
#
|
4
|
+
require 'rubygems'
|
5
|
+
require 'uri'
|
6
|
+
require 'net/http'
|
7
|
+
require 'open-uri'
|
8
|
+
require 'rss'
|
9
|
+
require 'nokogiri'
|
10
|
+
require 'shellwords'
|
11
|
+
require 'fileutils'
|
12
|
+
|
13
|
+
UrlRegexp = URI.regexp(['rtsp','http'])
|
14
|
+
|
15
|
+
#
|
16
|
+
#
|
17
|
+
class BBCNet
|
18
|
+
RtspRegexp = URI.regexp(['rtsp'])
|
19
|
+
MmsRegexp = URI.regexp(['mms'])
|
20
|
+
DirectStreamRegexp = URI.regexp(['mms', 'rtsp', 'rtmp', 'rtmpt'])
|
21
|
+
|
22
|
+
|
23
|
+
#------------------------------------------------------------------------
|
24
|
+
# get stream metadata
|
25
|
+
# episode url => pid => xml playlist => version pid (vpid aka. identifier)
|
26
|
+
# => xml stream metadata => wma
|
27
|
+
#
|
28
|
+
class MetaInfo
|
29
|
+
def self.get(url)
|
30
|
+
pid = BBCNet.extractPid(url)
|
31
|
+
# info = @@cachePid[pid]
|
32
|
+
# return info if info
|
33
|
+
self.new(pid)
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :pid
|
37
|
+
Keys = [ :duration, :vpid, :group, :media, :onAirDate, :channel, :title, :summary, :aacLow, :aacStd, :real, :wma, :streams ]
|
38
|
+
def initialize(pid)
|
39
|
+
@pid = pid
|
40
|
+
Keys.each do |k|
|
41
|
+
s = ('@' + k.to_s).to_sym
|
42
|
+
self.instance_variable_set(s, nil)
|
43
|
+
self.class.class_eval %Q{
|
44
|
+
def #{k}
|
45
|
+
#{s}
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
@streams = []
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
#
|
55
|
+
# read duration, vpid, group, media, onAirDate, channel
|
56
|
+
# from XmlPlaylist
|
57
|
+
def readXmlPlaylist
|
58
|
+
return self if @vpid
|
59
|
+
|
60
|
+
res = BBCNet.read("http://www.bbc.co.uk/iplayer/playlist/#{@pid}")
|
61
|
+
# res = IO.read("../tmp/iplayer-playlist-me.xml")
|
62
|
+
|
63
|
+
doc = Nokogiri::XML(res)
|
64
|
+
item = doc.at_css("item")
|
65
|
+
@media = item[:kind].gsub(/programme/i, '')
|
66
|
+
@duration = item[:duration].to_i
|
67
|
+
@vpid = item[:identifier]
|
68
|
+
@group = item[:group]
|
69
|
+
@onAirDate = BBCNet.getTime(item.at_css("broadcast").content.to_s)
|
70
|
+
@channel = item.at_css("service").content.to_s
|
71
|
+
@title = item.at_css("title").content.to_s
|
72
|
+
@summary = doc.at_css("summary").content.to_s
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
class StreamInfo
|
78
|
+
# example) 48, wma, time, audio, http://..
|
79
|
+
attr_accessor :bitrate, :encoding, :expires, :type, :indirectUrl
|
80
|
+
alias :kind :type
|
81
|
+
|
82
|
+
def url
|
83
|
+
@url ||= BBCNet.getDirectStreamUrl(@indirectUrl)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def readXmlStreamMeta
|
88
|
+
readXmlPlaylist unless @vpid
|
89
|
+
|
90
|
+
res = BBCNet.read("http://www.bbc.co.uk/mediaselector/4/mtis/stream/#{vpid}")
|
91
|
+
# res = IO.read("../tmp/iplayer-stream-meta-me.xml")
|
92
|
+
|
93
|
+
doc = Nokogiri::XML(res)
|
94
|
+
me = doc.css("media")
|
95
|
+
me.each do |m|
|
96
|
+
stmInf = StreamInfo.new
|
97
|
+
stmInf.encoding = m[:encoding] # wma
|
98
|
+
stmInf.bitrate = m[:bitrate].to_i # 48
|
99
|
+
expiresStr = m[:expires]
|
100
|
+
stmInf.expires = BBCNet.getTime(expiresStr) if expiresStr
|
101
|
+
stmInf.type = m[:kind] # audio
|
102
|
+
|
103
|
+
con = m.at_css("connection")
|
104
|
+
stmInf.indirectUrl = con[:href]
|
105
|
+
@streams <<= stmInf
|
106
|
+
|
107
|
+
case stmInf.encoding
|
108
|
+
when /\bwma\b/i
|
109
|
+
@wma = stmInf
|
110
|
+
when /\baac\b/i
|
111
|
+
if stmInf.bitrate < 64
|
112
|
+
@aacLow = stmInf
|
113
|
+
else
|
114
|
+
@aacStd = stmInf
|
115
|
+
end
|
116
|
+
when /\breal\b/i
|
117
|
+
@real = stmInf
|
118
|
+
end
|
119
|
+
end
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
alias :update :readXmlStreamMeta
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
def self.getTime(str)
|
130
|
+
tm = str.match(/(\d{4})-(\d\d)-(\d\d)\w(\d\d):(\d\d):(\d\d)/)
|
131
|
+
par = ((1..6).inject([]) do |a, n| a << tm[n].to_i end)
|
132
|
+
Time.gm( *par )
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
#------------------------------------------------------------------------
|
137
|
+
#
|
138
|
+
#
|
139
|
+
|
140
|
+
# convert epsode Url to console Url
|
141
|
+
# example
|
142
|
+
# from
|
143
|
+
# http://www.bbc.co.uk/iplayer/episode/b007jpkt/Miss_Marple_A_Caribbean_Mystery_Episode_1/
|
144
|
+
# to
|
145
|
+
# http://www.bbc.co.uk/iplayer/console/b007jpkt
|
146
|
+
def self.getPlayerConsoleUrl(url)
|
147
|
+
"http://www.bbc.co.uk/iplayer/console/" + extractPid(url)
|
148
|
+
end
|
149
|
+
|
150
|
+
# get PID from BBC episode Url
|
151
|
+
def self.extractPid(url)
|
152
|
+
case url
|
153
|
+
when %r!/(?:item|episode|programmes)/([a-z0-9]{8})!
|
154
|
+
$1
|
155
|
+
when %r!^[a-z0-9]{8}$!
|
156
|
+
url
|
157
|
+
when %r!\b(b[a-z0-9]{7}\b)!
|
158
|
+
$1
|
159
|
+
else
|
160
|
+
raise "No PID in Url '%s'" % url
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
# .asf/.ram => .wma/.ra
|
166
|
+
def self.getDirectStreamUrl(url)
|
167
|
+
unless url[DirectStreamRegexp] then
|
168
|
+
res = self.read(url)
|
169
|
+
newSrc= res[ DirectStreamRegexp ]
|
170
|
+
url = newSrc unless newSrc.nil?
|
171
|
+
end
|
172
|
+
url
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
def self.read(url)
|
177
|
+
header = { "User-Agent" => self.randomUserAgent }
|
178
|
+
if defined? @@proxy
|
179
|
+
header[:proxy] = @@proxy
|
180
|
+
end
|
181
|
+
|
182
|
+
uri = URI.parse(url)
|
183
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
184
|
+
http.get(uri.path, header)
|
185
|
+
end
|
186
|
+
res.body
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.setProxy(url)
|
190
|
+
@@proxy = url
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
UserAgentList = [
|
195
|
+
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/<RAND>.8 (KHTML, like Gecko) Chrome/2.0.178.0 Safari/<RAND>.8',
|
196
|
+
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; YPC 3.2.0; SLCC1; .NET CLR 2.0.50<RAND>; .NET CLR 3.0.04<RAND>)',
|
197
|
+
'Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; tr) AppleWebKit/<RAND>.4+ (KHTML, like Gecko) Version/4.0dp1 Safari/<RAND>.11.2',
|
198
|
+
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50<RAND>; .NET CLR 3.5.30<RAND>; .NET CLR 3.0.30<RAND>; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8)',
|
199
|
+
'Mozilla/6.0 (Windows; U; Windows NT 7.0; en-US; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.9 (.NET CLR 3.5.30<RAND>)',
|
200
|
+
]
|
201
|
+
def self.randomUserAgent
|
202
|
+
ua = UserAgentList[ rand UserAgentList.length ]
|
203
|
+
ua.gsub(/<RAND>/, "%03d" % rand(1000))
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
module AudioFile
|
209
|
+
# return seconds of audio file duration.
|
210
|
+
def self.getDuration(file)
|
211
|
+
case file[/\.\w+$/].downcase
|
212
|
+
when ".mp3"
|
213
|
+
cmd = "| exiftool -S -Duration %s" % file.shellescape
|
214
|
+
when ".wma"
|
215
|
+
cmd = "| exiftool -S -PlayDuration %s" % file.shellescape
|
216
|
+
end
|
217
|
+
msg = open(cmd) do |f| f.read end
|
218
|
+
a = msg.scan(/(?:(\d+):){0,2}(\d+)/)[0]
|
219
|
+
i = -1
|
220
|
+
a.reverse.inject(0) do |s, d|
|
221
|
+
i += 1
|
222
|
+
s + d.to_i * [ 1, 60, 3600 ][i]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
if __FILE__ == $0 then
|
230
|
+
puts AudioFile::getDuration(ARGV.shift)
|
231
|
+
exit 0
|
232
|
+
|
233
|
+
pid = "b00mzvfq"
|
234
|
+
if ARGV.size > 0 then
|
235
|
+
pid = ARGV.shift
|
236
|
+
end
|
237
|
+
minfo = BBCNet::MetaInfo.new(pid)
|
238
|
+
minfo.readXmlStreamMeta
|
239
|
+
puts minfo.inspect
|
240
|
+
|
241
|
+
minfo.streams.each do |s|
|
242
|
+
puts "url : " + s.url
|
243
|
+
end
|
244
|
+
end
|
data/lib/download.rb
ADDED
@@ -0,0 +1,325 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require "bbcnet.rb"
|
4
|
+
|
5
|
+
#-------------------------------------------------------------------
|
6
|
+
#
|
7
|
+
#
|
8
|
+
#
|
9
|
+
class DownloadProcess < Qt::Process
|
10
|
+
slots 'taskFinished(int,QProcess::ExitStatus)'
|
11
|
+
attr_reader :sourceUrl, :fileName
|
12
|
+
attr_accessor :taskItem
|
13
|
+
|
14
|
+
#
|
15
|
+
DEBUG_DOWNLOAD = false
|
16
|
+
|
17
|
+
# @stage
|
18
|
+
DOWNLOAD = 0
|
19
|
+
CONVERT = 1
|
20
|
+
FINISHED = 2
|
21
|
+
|
22
|
+
# @status
|
23
|
+
INITIAL = 0
|
24
|
+
RUNNING = 1
|
25
|
+
ERROR = 2
|
26
|
+
DONE = 3
|
27
|
+
def statusMessage
|
28
|
+
case @status
|
29
|
+
when INITIAL, RUNNING, DONE
|
30
|
+
%w{ Downloading Converting Finished }[@stage]
|
31
|
+
when ERROR
|
32
|
+
"Error : " + %w{ Download Convert Finish }[@stage]
|
33
|
+
else
|
34
|
+
"???"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def status=(st)
|
39
|
+
@status = st
|
40
|
+
@taskItem.status = statusMessage if @taskItem
|
41
|
+
$log.misc { "status:#{status}" }
|
42
|
+
end
|
43
|
+
|
44
|
+
#--------------------------
|
45
|
+
# check status
|
46
|
+
def running?
|
47
|
+
@status == RUNNING
|
48
|
+
end
|
49
|
+
|
50
|
+
def error?
|
51
|
+
@status == ERROR
|
52
|
+
end
|
53
|
+
|
54
|
+
#--------------------------
|
55
|
+
# check stage
|
56
|
+
def finished?
|
57
|
+
@stage == FINISHED
|
58
|
+
end
|
59
|
+
|
60
|
+
def rawDownloaded?
|
61
|
+
@stage >= CONVERT
|
62
|
+
end
|
63
|
+
|
64
|
+
class Command
|
65
|
+
attr_accessor :app, :args, :msg
|
66
|
+
def initialize(app, args, msg)
|
67
|
+
@app = app
|
68
|
+
@args = args
|
69
|
+
@msg = msg
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
attr_reader :sourceUrl, :rawFileName
|
74
|
+
|
75
|
+
def initialize(parent, metaInfo, fName)
|
76
|
+
super(parent)
|
77
|
+
@metaInfo = metaInfo
|
78
|
+
@parent = parent
|
79
|
+
@taskItem = nil
|
80
|
+
@startTime = Time.new
|
81
|
+
@sourceUrl = @metaInfo.wma.url
|
82
|
+
@rawFileName = fName
|
83
|
+
@rawFilePath = File.join(IRecSettings.rawDownloadDir.path, fName)
|
84
|
+
mkdirSavePath(@rawFilePath)
|
85
|
+
$log.debug { "@rawFilePath : #{@rawFilePath }" }
|
86
|
+
|
87
|
+
@stage = DOWNLOAD
|
88
|
+
@status = INITIAL
|
89
|
+
|
90
|
+
connect(self, SIGNAL('finished(int,QProcess::ExitStatus)'), self, SLOT('taskFinished(int,QProcess::ExitStatus)') )
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def beginTask
|
95
|
+
# 1st stage : download
|
96
|
+
if File.exist?(@rawFilePath) then
|
97
|
+
@stage = CONVERT
|
98
|
+
@outFileName = @rawFileName.gsub(/\.\w+$/i, '.mp3')
|
99
|
+
@outFilePath = File.join(IRecSettings.downloadDir.path, @outFileName)
|
100
|
+
$log.debug { "@rawFilePath duration:" + AudioFile.getDuration(@rawFilePath).to_s }
|
101
|
+
$log.debug { "@outFilePath duration:" + AudioFile.getDuration(@outFilePath).to_s }
|
102
|
+
$log.debug { "metainf duration:" + @metaInfo.duration.to_s }
|
103
|
+
if File.exist?(@outFilePath) then
|
104
|
+
taskFinished(1,0)
|
105
|
+
else
|
106
|
+
$log.debug { "begin convert" }
|
107
|
+
beginConvert
|
108
|
+
return
|
109
|
+
end
|
110
|
+
else
|
111
|
+
beginDownload
|
112
|
+
end
|
113
|
+
|
114
|
+
# beginDownload
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
def retryTask
|
119
|
+
$log.debug { "retry! in main." }
|
120
|
+
if error? then
|
121
|
+
# retry
|
122
|
+
case @stage
|
123
|
+
when DOWNLOAD
|
124
|
+
@startTime = Time.new
|
125
|
+
beginDownload
|
126
|
+
when CONVERT
|
127
|
+
@startTime = Time.new
|
128
|
+
beginConvert
|
129
|
+
end
|
130
|
+
else
|
131
|
+
$log.warn { "cannot retry the successfully finished or running process." }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def cancelTask
|
136
|
+
if running? then
|
137
|
+
self.terminate
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def updateLapse
|
142
|
+
taskItem.updateTime(lapse)
|
143
|
+
end
|
144
|
+
|
145
|
+
def lapse
|
146
|
+
Time.now - @startTime
|
147
|
+
end
|
148
|
+
|
149
|
+
# slot :
|
150
|
+
def taskFinished(exitCode, exitStatus)
|
151
|
+
checkReadOutput
|
152
|
+
if (exitCode.to_i.nonzero? || exitStatus.to_i.nonzero?) && checkErroredStatus then
|
153
|
+
self.status = ERROR
|
154
|
+
$log.error { [ makeErrorMsg, "exitCode=#{exitCode}, exitStatus=#{exitStatus}" ] }
|
155
|
+
else
|
156
|
+
$log.info {
|
157
|
+
[ "Successed to download a File '%#2$s'",
|
158
|
+
"Successed to convert a File '%#2$s'", ][@stage] %
|
159
|
+
[ @sourceUrl, @rawFilePath ]
|
160
|
+
}
|
161
|
+
nextTask
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def updateView
|
166
|
+
if running? then
|
167
|
+
# update Lapse time
|
168
|
+
updateLapse
|
169
|
+
|
170
|
+
# dump IO message buffer
|
171
|
+
checkReadOutput
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
protected
|
177
|
+
# increment stage
|
178
|
+
def nextTask
|
179
|
+
@stage += 1
|
180
|
+
case @stage
|
181
|
+
when DOWNLOAD
|
182
|
+
beginDownload
|
183
|
+
when CONVERT
|
184
|
+
beginConvert
|
185
|
+
else
|
186
|
+
removeRawFile
|
187
|
+
allTaskFinished
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def beginDownload
|
192
|
+
$log.info { " DownloadProcess : beginDownload." }
|
193
|
+
@stage = DOWNLOAD
|
194
|
+
@downNG = true
|
195
|
+
self.status = RUNNING
|
196
|
+
@currentCommand = makeMPlayerDownloadCmd
|
197
|
+
|
198
|
+
$log.info { @currentCommand.msg }
|
199
|
+
start(@currentCommand.app, @currentCommand.args)
|
200
|
+
end
|
201
|
+
|
202
|
+
def makeMPlayerDownloadCmd
|
203
|
+
# make MPlayer Downlaod comand
|
204
|
+
cmdMsg = "mplayer -noframedrop -dumpfile %s -dumpstream %s" %
|
205
|
+
[@rawFilePath.shellescape, @sourceUrl.shellescape]
|
206
|
+
cmdApp = "mplayer"
|
207
|
+
cmdArgs = ['-noframedrop', '-dumpfile', @rawFilePath, '-dumpstream', @sourceUrl]
|
208
|
+
|
209
|
+
# debug code.
|
210
|
+
if DEBUG_DOWNLOAD then
|
211
|
+
if rand > 0.4 then
|
212
|
+
cmdApp = "test/sleepjob.rb"
|
213
|
+
cmdArgs = %w{ touch a/b/ }
|
214
|
+
else
|
215
|
+
cmdApp = "test/sleepjob.rb"
|
216
|
+
cmdArgs = %w{ touch } << @rawFilePath.shellescape
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
Command.new( cmdApp, cmdArgs, cmdMsg )
|
221
|
+
end
|
222
|
+
|
223
|
+
def beginConvert
|
224
|
+
@stage = CONVERT
|
225
|
+
self.status = RUNNING
|
226
|
+
@outFileName = @rawFileName.gsub(/\.\w+$/i, '.mp3')
|
227
|
+
@outFilePath = File.join(IRecSettings.downloadDir.path, @outFileName)
|
228
|
+
mkdirSavePath(@outFilePath)
|
229
|
+
|
230
|
+
cmdMsg = "nice -n 19 ffmpeg -i %s -f mp3 %s" %
|
231
|
+
[ @rawFilePath.shellescape, @outFilePath.shellescape]
|
232
|
+
cmdApp = "nice"
|
233
|
+
cmdArgs = [ '-n', '19', 'ffmpeg', '-i', @rawFilePath, '-f', 'mp3', @outFilePath ]
|
234
|
+
|
235
|
+
|
236
|
+
# debug code.
|
237
|
+
if DEBUG_DOWNLOAD then
|
238
|
+
if rand > 0.4 then
|
239
|
+
cmdApp = "test/sleepjob.rb"
|
240
|
+
cmdArgs = %w{ touch a/b/ }
|
241
|
+
else
|
242
|
+
cmdApp = "test/sleepjob.rb"
|
243
|
+
cmdArgs = %w{ cp -f } + [ @rawFilePath.shellescape, @outFilePath.shellescape ]
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
@currentCommand = Command.new( cmdApp, cmdArgs, cmdMsg )
|
248
|
+
$log.info { @currentCommand.msg }
|
249
|
+
start(@currentCommand.app, @currentCommand.args)
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
def removeRawFile
|
254
|
+
unless IRecSettings.leaveRawFile then
|
255
|
+
begin
|
256
|
+
File.delete(@rawFilePath)
|
257
|
+
rescue => e
|
258
|
+
$log.error { e }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def checkOutput(msg)
|
264
|
+
msgSum = msg.join(' ')
|
265
|
+
@downNG &&= false if msgSum =~ /Everything done/i
|
266
|
+
end
|
267
|
+
|
268
|
+
# check and read output
|
269
|
+
def checkReadOutput
|
270
|
+
msg = readAllStandardOutput.data .reject do |l| l.empty? end
|
271
|
+
checkOutput(msg)
|
272
|
+
$log.info { msg }
|
273
|
+
end
|
274
|
+
|
275
|
+
# return error or not
|
276
|
+
def checkErroredStatus
|
277
|
+
case @stage
|
278
|
+
when DOWNLOAD
|
279
|
+
return @downNG if @downNG
|
280
|
+
begin
|
281
|
+
$log.debug { "check duration for download." }
|
282
|
+
AudioFile.getDuration(@rawFilePath) < @metaInfo.duration - 5
|
283
|
+
rescue => e
|
284
|
+
$log.info{ e }
|
285
|
+
true
|
286
|
+
end
|
287
|
+
when CONVERT
|
288
|
+
begin
|
289
|
+
$log.debug { "check duration for convert." }
|
290
|
+
AudioFile.getDuration(@outFilePath) < @metaInfo.duration - 40
|
291
|
+
rescue => e
|
292
|
+
$log.info{ e }
|
293
|
+
true
|
294
|
+
end
|
295
|
+
else
|
296
|
+
true
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
protected
|
304
|
+
def allTaskFinished
|
305
|
+
@stage = FINISHED
|
306
|
+
self.status = DONE
|
307
|
+
end
|
308
|
+
|
309
|
+
def makeErrorMsg
|
310
|
+
[ "Failed to download a File '%#2$s'",
|
311
|
+
"Failed to convert a File '%#2$s'", ][@stage] %
|
312
|
+
[ @sourceUrl, @rawFilePath ]
|
313
|
+
end
|
314
|
+
|
315
|
+
|
316
|
+
def mkdirSavePath(fName)
|
317
|
+
dir = File.dirname(fName)
|
318
|
+
unless File.exist? dir
|
319
|
+
$log.info{ "mkdir : " + dir }
|
320
|
+
FileUtils.mkdir_p(dir)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
|