svt-recorder 1.0.0 → 1.0.1
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/ChangeLog +13 -0
- data/Gemfile +1 -1
- data/bin/svt-recorder +6 -11
- data/lib/svt/recorder.rb +1 -1
- data/lib/svt/recorder/base.rb +19 -5
- data/lib/svt/recorder/rapport.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/rapport.html +2 -2
- data/spec/support/streams-with-http.m3u8 +13 -0
- data/spec/svt_recorder_play_spec.rb +14 -1
- data/svt-recorder.gemspec +1 -1
- metadata +48 -16
data/ChangeLog
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
2012-09-09 Björn Andersson <ba@sanitarium.se>, v1.0.1
|
2
|
+
|
3
|
+
User request for a better progress bar, so I've obliged with the
|
4
|
+
excellent `progress_bar` gem by Paul Sadauskas.
|
5
|
+
https://github.com/paul/progress_bar
|
6
|
+
|
7
|
+
* svt-recorder uses a new progress bar that estimates time to
|
8
|
+
completion, shows how long the download has been going on and
|
9
|
+
also displays how many chunks that has been downloaded together
|
10
|
+
with the total number of chunks.
|
11
|
+
* SVT::Recorder.fetch_playlist doesn't need to be called with
|
12
|
+
a block anymore.
|
13
|
+
|
1
14
|
2012-06-04 Björn Andersson <ba@sanitarium.se>, v1.0.0
|
2
15
|
|
3
16
|
SVT has changed their website and thus the way data is fetched.
|
data/Gemfile
CHANGED
data/bin/svt-recorder
CHANGED
@@ -12,6 +12,7 @@ end
|
|
12
12
|
require 'tempfile'
|
13
13
|
require 'readline'
|
14
14
|
require 'ostruct'
|
15
|
+
require 'progress_bar'
|
15
16
|
|
16
17
|
if ARGV.empty? or ARGV[0].match(/\A(-h)|((--)?help)\Z/i)
|
17
18
|
puts "Usage: #{$0.split(/\//)[-1]} <SVT Play URL> [name of output file]"
|
@@ -31,7 +32,6 @@ class HTTPDownload
|
|
31
32
|
@downloader = downloader
|
32
33
|
@headers = {'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10'}
|
33
34
|
@file = output
|
34
|
-
|
35
35
|
@server = Net::HTTP.start(@base_url.host, @base_url.port)
|
36
36
|
|
37
37
|
if block_given?
|
@@ -53,15 +53,8 @@ class HTTPDownload
|
|
53
53
|
begin
|
54
54
|
@server.request_get(File.join(@base_url.path, part),
|
55
55
|
@headers) do |res|
|
56
|
-
|
57
56
|
res.read_body do |body|
|
58
57
|
file.write body
|
59
|
-
downloaded += body.size
|
60
|
-
|
61
|
-
if downloaded >= megabyte
|
62
|
-
downloaded -= megabyte
|
63
|
-
yield mb_down += 1
|
64
|
-
end
|
65
58
|
end
|
66
59
|
end # /@server
|
67
60
|
rescue Timeout::Error
|
@@ -69,7 +62,9 @@ class HTTPDownload
|
|
69
62
|
@server = Net::HTTP.start(@base_url.host, @base_url.port)
|
70
63
|
retry
|
71
64
|
end
|
72
|
-
|
65
|
+
|
66
|
+
yield part
|
67
|
+
end # /parts
|
73
68
|
end # /File
|
74
69
|
end
|
75
70
|
|
@@ -102,8 +97,8 @@ if File.exists? output_file
|
|
102
97
|
exit 1 unless overwrite.match(/Y/i)
|
103
98
|
end
|
104
99
|
|
100
|
+
progress = ProgressBar.new(downloader.parts?, :bar, :elapsed, :eta, :counter)
|
105
101
|
HTTPDownload.new(downloader, output_file) do |down|
|
106
|
-
|
107
|
-
down.fetch_all {|part| print (part > 0)? '.': 'r' }
|
102
|
+
down.fetch_all {|part| progress.increment! }
|
108
103
|
puts "\nFinished recording: #{output_file}"
|
109
104
|
end
|
data/lib/svt/recorder.rb
CHANGED
data/lib/svt/recorder/base.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# -*- coding: utf-8 -*-
|
3
|
+
require 'cgi'
|
3
4
|
|
4
5
|
module SVT
|
5
6
|
module Recorder
|
@@ -16,6 +17,7 @@ module SVT
|
|
16
17
|
# url :: The URL from data-json-href, Play have to add modify the URL
|
17
18
|
# to make it absolute. So the caller makes any modifications
|
18
19
|
# before the JSON-file gets fetched.
|
20
|
+
# Not required to work.
|
19
21
|
#
|
20
22
|
# Returns:
|
21
23
|
# A hash with these keys:
|
@@ -24,18 +26,18 @@ module SVT
|
|
24
26
|
def self.fetch_playlist(url, css_path)
|
25
27
|
doc = Nokogiri::HTML(open(url).read)
|
26
28
|
player = doc.at_css(css_path)
|
27
|
-
stream = player['data-json-href']
|
28
|
-
stream = yield stream
|
29
|
+
stream = CGI.unescape(player['data-json-href'])
|
30
|
+
stream = yield stream if block_given?
|
29
31
|
|
30
32
|
js = JSON.parse(open(stream).read)
|
31
33
|
if not js['video']['availableOnMobile']
|
32
|
-
raise ArgumentError, "The passed in URL is not available for mobile
|
34
|
+
raise ArgumentError, "The passed in URL is not available for mobile"
|
33
35
|
end
|
34
36
|
|
35
37
|
title = js['context']['title']
|
36
38
|
v = js['video']['videoReferences'].find({}) {|v| v['playerType'] == 'ios' }
|
37
39
|
|
38
|
-
{:title => title, :url => v['url']}
|
40
|
+
return({:title => title, :url => CGI.unescape(v['url'])}) if not v.empty?
|
39
41
|
end
|
40
42
|
|
41
43
|
class Base
|
@@ -115,6 +117,16 @@ module SVT
|
|
115
117
|
end
|
116
118
|
end
|
117
119
|
|
120
|
+
# Returns the number of parts this recording got
|
121
|
+
#
|
122
|
+
# Returns:
|
123
|
+
# int the numbers of parts, 0 index
|
124
|
+
def parts?
|
125
|
+
part_urls() if @last_part == 0
|
126
|
+
|
127
|
+
return @last_part
|
128
|
+
end
|
129
|
+
|
118
130
|
# Yields all +parts+ concatenated with base_url
|
119
131
|
def all_parts
|
120
132
|
parts do |part|
|
@@ -124,6 +136,7 @@ module SVT
|
|
124
136
|
|
125
137
|
#--
|
126
138
|
# A naïve parser, but until it turns out to be a problem it'll do.
|
139
|
+
# 2012=09-09: If a FQDN address is given only return the basename
|
127
140
|
#
|
128
141
|
# The format is:
|
129
142
|
# EXT-X-.... BANDWIDTH=<bitrate>
|
@@ -132,9 +145,10 @@ module SVT
|
|
132
145
|
bitrate = nil
|
133
146
|
open(@stream).each do |row|
|
134
147
|
row.strip!
|
148
|
+
row = File.basename(row) if row.match(/^http/)
|
135
149
|
|
136
150
|
if bitrate
|
137
|
-
@bitrates[bitrate] = row
|
151
|
+
@bitrates[bitrate] = CGI.escape(row)
|
138
152
|
bitrate = nil
|
139
153
|
end
|
140
154
|
|
data/lib/svt/recorder/rapport.rb
CHANGED
@@ -15,7 +15,7 @@ module SVT
|
|
15
15
|
# Usage is the same as for SVT::Recorder::Play.
|
16
16
|
class Rapport < Base
|
17
17
|
def initialize(url)
|
18
|
-
video = SVT::Recorder.fetch_playlist(url, '.svtplayer')
|
18
|
+
video = SVT::Recorder.fetch_playlist(url, '.svtplayer')
|
19
19
|
|
20
20
|
super(video)
|
21
21
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/rapport.html
CHANGED
@@ -415,7 +415,7 @@ data-title=""Jag var jättestressad i finalen" - SVT.se"
|
|
415
415
|
data-length="535"
|
416
416
|
data-id="113083"
|
417
417
|
data-popout-href="http://svt.se/wd?widgetId=32050&sectionId=532&articleId=113083&type=embed&contextSectionId=532"
|
418
|
-
data-json-href="
|
418
|
+
data-json-href="spec/support/rapport.json"
|
419
419
|
data-embed-href="http://svt.se/wd?widgetId=32050&sectionId=532&articleId=113083&type=embed&contextSectionId=532"
|
420
420
|
data-disabled="end">
|
421
421
|
<img class="svtJsReplaceImage svtPlayerImage" alt=" " src="/svts/article113082.svt/ALTERNATES/large/default_title" />
|
@@ -772,4 +772,4 @@ $(document).ready(function() {
|
|
772
772
|
<img src="http://ld.svt.se/svt/svt/s?svtse.nyheter.nyhetsklipp.nyheter.%22jag-var-j%C3%A4ttestressad-i-finalen%22&svt_section_id=532&svt_program_name=nyheter&svt_section_name=nyheter&svt_article_title=%22jag-var-j%C3%A4ttestressad-i-finalen%22&svt_context_id=532&svt_context_name=nyheter&svt_cat_name=nyheter&svt_article_type=videoklipp&svt_article_id=113083&client=web" width="1" height="1" alt=""/>
|
773
773
|
</noscript>
|
774
774
|
<script type="text/javascript">if (!NREUMQ.f) { NREUMQ.f=function() {NREUMQ.push(["load",new Date().getTime()]);var e=document.createElement("script");e.type="text/javascript";e.src=(("http:"===document.location.protocol)?"http:":"https:") + "//" + "d1ros97qkrwjf5.cloudfront.net/34/eum/rum.js";document.body.appendChild(e);if(NREUMQ.a)NREUMQ.a();};NREUMQ.a=window.onload;window.onload=NREUMQ.f;};NREUMQ.push(["nrfj","beacon-1.newrelic.com","7aa7765553",908109,"bwdWYRFVV0AEU0BfDlZNfmYzG01WCEBYVxVdTVdaDllWXUtaR0Y=",0,297,new Date().getTime(),"","","","",""]);</script></body>
|
775
|
-
</html>
|
775
|
+
</html>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#EXTM3U
|
2
|
+
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=258450
|
3
|
+
http://whatever.ding.se/hej/PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer1_vod.m3u8
|
4
|
+
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=697107
|
5
|
+
http://whatever.ding.se/hej/PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer2_vod.m3u8
|
6
|
+
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=143234
|
7
|
+
http://whatever.ding.se/hej/PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer3_vod.m3u8
|
8
|
+
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=49212
|
9
|
+
http://whatever.ding.se/hej/PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer4_vod.m3u8
|
10
|
+
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1364631
|
11
|
+
http://whatever.ding.se/hej/PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer5_vod.m3u8
|
12
|
+
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=2498313, CODECS="avc1.4d001f"
|
13
|
+
http://whatever.ding.se/hej/PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer6_vod.m3u8
|
@@ -21,6 +21,14 @@ module SVT
|
|
21
21
|
|
22
22
|
data.title.should == title
|
23
23
|
end
|
24
|
+
|
25
|
+
it 'should handle streams with http and just give of the basename' do
|
26
|
+
# An error when fetching Rapport videos, the playlist at times had
|
27
|
+
# a FQDN
|
28
|
+
data = SVT::Recorder::Base.new({:url => $stream_http,
|
29
|
+
:title => 'Whatever'})
|
30
|
+
data.parts[0].should == 'PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer6/3512_Period1/segment0.ts'
|
31
|
+
end
|
24
32
|
end
|
25
33
|
|
26
34
|
let(:title) { 'Glödlampskonspirationen' }
|
@@ -87,7 +95,12 @@ module SVT
|
|
87
95
|
recorder.parts[0].should == 'PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer6/3512_Period1/segment0.ts'
|
88
96
|
end
|
89
97
|
end
|
98
|
+
|
99
|
+
describe '#parts?' do
|
100
|
+
it 'should return the amount of parts in this recording' do
|
101
|
+
recorder.parts?().should == no_parts
|
102
|
+
end
|
103
|
+
end
|
90
104
|
end # /Play
|
91
105
|
end # /Recorder
|
92
106
|
end # /SVT
|
93
|
-
|
data/svt-recorder.gemspec
CHANGED
@@ -20,6 +20,6 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.rdoc_options << '-x spec --main lib/svt/recorder.rb --line-numbers'
|
21
21
|
s.add_dependency('json_pure', '~> 1.0')
|
22
22
|
s.add_dependency('nokogiri', '~> 1.0')
|
23
|
+
s.add_dependency('progress_bar', '~> 0.4')
|
23
24
|
s.add_development_dependency('rspec', '~> 2.0.0')
|
24
25
|
end
|
25
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: svt-recorder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json_pure
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,21 +21,47 @@ dependencies:
|
|
21
21
|
version: '1.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: nokogiri
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
41
|
none: false
|
29
42
|
requirements:
|
30
43
|
- - ~>
|
31
44
|
- !ruby/object:Gem::Version
|
32
45
|
version: '1.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: progress_bar
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.4'
|
33
54
|
type: :runtime
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.4'
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
63
|
name: rspec
|
38
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ~>
|
@@ -43,7 +69,12 @@ dependencies:
|
|
43
69
|
version: 2.0.0
|
44
70
|
type: :development
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.0.0
|
47
78
|
description: A program that helps you record videos from SVTPlay.se and PlayRapport.se
|
48
79
|
email: ba@sanitarium.se
|
49
80
|
executables:
|
@@ -58,21 +89,22 @@ files:
|
|
58
89
|
- Gemfile
|
59
90
|
- svt-recorder.gemspec
|
60
91
|
- ChangeLog
|
61
|
-
- lib/svt/recorder.rb
|
62
92
|
- lib/svt/recorder/base.rb
|
63
|
-
- lib/svt/recorder/rapport.rb
|
64
93
|
- lib/svt/recorder/play.rb
|
65
|
-
-
|
94
|
+
- lib/svt/recorder/rapport.rb
|
95
|
+
- lib/svt/recorder.rb
|
66
96
|
- spec/spec_helper.rb
|
67
97
|
- spec/svt_recorder_play_spec.rb
|
98
|
+
- spec/svt_recorder_rapport_spec.rb
|
68
99
|
- spec/svt_recorder_spec.rb
|
69
|
-
- spec/support/109244-nomobile
|
70
100
|
- spec/support/109244
|
101
|
+
- spec/support/109244-nomobile
|
71
102
|
- spec/support/example-page.html
|
72
|
-
- spec/support/
|
103
|
+
- spec/support/faulty-example-page.html
|
73
104
|
- spec/support/PG-1279307-001A-DOKUMENTUTIFRAN-02-hts-a-v1_Layer6_vod.m3u8
|
74
105
|
- spec/support/rapport.html
|
75
|
-
- spec/support/
|
106
|
+
- spec/support/rapport.json
|
107
|
+
- spec/support/streams-with-http.m3u8
|
76
108
|
- spec/support/streams.m3u8
|
77
109
|
- bin/svt-recorder
|
78
110
|
homepage: http://github.com/gaqzi/svt-recorder
|
@@ -96,11 +128,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
128
|
version: '0'
|
97
129
|
requirements: []
|
98
130
|
rubyforge_project:
|
99
|
-
rubygems_version: 1.8.
|
131
|
+
rubygems_version: 1.8.24
|
100
132
|
signing_key:
|
101
133
|
specification_version: 3
|
102
134
|
summary: A program that helps you record videos from SVTPlay.se and PlayRapport.se
|
103
135
|
test_files:
|
104
|
-
- spec/svt_recorder_rapport_spec.rb
|
105
136
|
- spec/svt_recorder_play_spec.rb
|
137
|
+
- spec/svt_recorder_rapport_spec.rb
|
106
138
|
- spec/svt_recorder_spec.rb
|