aviglitch 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/ChangeLog.md +8 -0
- data/Gemfile +5 -0
- data/README.md +0 -4
- data/aviglitch.gemspec +1 -2
- data/bin/datamosh +6 -1
- data/lib/aviglitch/avi.rb +550 -0
- data/lib/aviglitch/base.rb +29 -59
- data/lib/aviglitch/frame.rb +20 -0
- data/lib/aviglitch/frames.rb +167 -184
- data/lib/aviglitch.rb +2 -3
- data/spec/avi2_spec.rb +40 -0
- data/spec/aviglitch_spec.rb +2 -19
- data/spec/datamosh_spec.rb +4 -14
- data/spec/frames_spec.rb +34 -25
- data/spec/spec_helper.rb +41 -0
- metadata +6 -5
- data/spec/files/sample.avi +0 -0
data/lib/aviglitch.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'tempfile'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'readline'
|
4
2
|
require 'pathname'
|
5
3
|
require 'stringio'
|
4
|
+
require 'aviglitch/avi'
|
6
5
|
require 'aviglitch/base'
|
7
6
|
require 'aviglitch/frame'
|
8
7
|
require 'aviglitch/frames'
|
@@ -31,7 +30,7 @@ require 'aviglitch/frames'
|
|
31
30
|
#
|
32
31
|
module AviGlitch
|
33
32
|
|
34
|
-
VERSION = '0.
|
33
|
+
VERSION = '0.2.0'
|
35
34
|
|
36
35
|
BUFFER_SIZE = 2 ** 24
|
37
36
|
|
data/spec/avi2_spec.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe AviGlitch, 'AVI2.0' do
|
4
|
+
|
5
|
+
it 'should save same file when nothing has changed' do
|
6
|
+
avi = AviGlitch.open @in2
|
7
|
+
avi.glitch do |d|
|
8
|
+
d
|
9
|
+
end
|
10
|
+
avi.output @out
|
11
|
+
FileUtils.cmp(@in2, @out).should be true
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be AVI1.0 when its size has reduced less than 1GB' do
|
15
|
+
a = AviGlitch.open @in2
|
16
|
+
size = 0
|
17
|
+
a.glitch do |d|
|
18
|
+
size += d.size
|
19
|
+
size < 1024 ** 3 ? d : nil
|
20
|
+
end
|
21
|
+
a.output @out
|
22
|
+
b = AviGlitch.open @out
|
23
|
+
b.avi.was_avi2?.should be false
|
24
|
+
b.close
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should be AVI2.0 when its size has increased over 1GB' do
|
28
|
+
a = AviGlitch.open @in
|
29
|
+
n = Math.log(1024.0 ** 3 / a.frames.data_size.to_f, 2).ceil
|
30
|
+
f = a.frames[0..-1]
|
31
|
+
n.times do
|
32
|
+
fx = f[0..-1]
|
33
|
+
f.concat fx
|
34
|
+
end
|
35
|
+
f.to_avi.output @out
|
36
|
+
b = AviGlitch.open @out
|
37
|
+
b.avi.was_avi2?.should be true
|
38
|
+
b.close
|
39
|
+
end
|
40
|
+
end
|
data/spec/aviglitch_spec.rb
CHANGED
@@ -2,24 +2,10 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe AviGlitch do
|
4
4
|
|
5
|
-
before :all do
|
6
|
-
FileUtils.mkdir OUTPUT_DIR unless File.exist? OUTPUT_DIR
|
7
|
-
@in = FILES_DIR + 'sample.avi'
|
8
|
-
@out = OUTPUT_DIR + 'out.avi'
|
9
|
-
end
|
10
|
-
|
11
|
-
after :each do
|
12
|
-
FileUtils.rm Dir.glob((OUTPUT_DIR + '*').to_s)
|
13
|
-
end
|
14
|
-
|
15
|
-
after :all do
|
16
|
-
FileUtils.rmdir OUTPUT_DIR
|
17
|
-
end
|
18
|
-
|
19
5
|
it 'should raise an error against unsupported files' do
|
20
6
|
lambda {
|
21
7
|
avi = AviGlitch.open __FILE__
|
22
|
-
}.should raise_error
|
8
|
+
}.should raise_error(RuntimeError)
|
23
9
|
end
|
24
10
|
|
25
11
|
it 'should return AviGlitch::Base object through the method #open' do
|
@@ -203,9 +189,6 @@ describe AviGlitch do
|
|
203
189
|
end
|
204
190
|
|
205
191
|
expect(dc1).to eq(dc2)
|
206
|
-
|
207
|
-
|
208
|
-
|
209
192
|
end
|
210
|
-
|
193
|
+
|
211
194
|
end
|
data/spec/datamosh_spec.rb
CHANGED
@@ -3,23 +3,12 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
3
|
describe AviGlitch, 'datamosh cli' do
|
4
4
|
|
5
5
|
before :all do
|
6
|
-
FileUtils.mkdir OUTPUT_DIR unless File.exist? OUTPUT_DIR
|
7
|
-
@in = FILES_DIR + 'sample.avi'
|
8
|
-
@out = OUTPUT_DIR + 'out.avi'
|
9
6
|
here = File.dirname(__FILE__)
|
10
7
|
lib = Pathname.new(File.join(here, '..', 'lib')).realpath
|
11
8
|
datamosh = Pathname.new(File.join(here, '..', 'bin/datamosh')).realpath
|
12
9
|
@cmd = "ruby -I%s %s -o %s " % [lib, datamosh, @out]
|
13
10
|
end
|
14
11
|
|
15
|
-
after :each do
|
16
|
-
FileUtils.rm Dir.glob((OUTPUT_DIR + '*').to_s)
|
17
|
-
end
|
18
|
-
|
19
|
-
after :all do
|
20
|
-
FileUtils.rmdir OUTPUT_DIR
|
21
|
-
end
|
22
|
-
|
23
12
|
it 'should correctly process files' do
|
24
13
|
a = AviGlitch.open @in
|
25
14
|
keys = a.frames.inject(0) do |c, f|
|
@@ -27,12 +16,13 @@ describe AviGlitch, 'datamosh cli' do
|
|
27
16
|
c
|
28
17
|
end
|
29
18
|
total = a.frames.size
|
19
|
+
first_keyframe = a.frames.index(a.frames.first_of(:keyframe))
|
30
20
|
a.close
|
31
21
|
|
32
22
|
system [@cmd, @in].join(' ')
|
33
23
|
o = AviGlitch.open @out
|
34
24
|
o.frames.size.should == total
|
35
|
-
o.frames.
|
25
|
+
o.frames[first_keyframe].is_keyframe?.should be true
|
36
26
|
o.has_keyframe?.should be true
|
37
27
|
o.close
|
38
28
|
AviGlitch::Base.surely_formatted?(@out, true).should be true
|
@@ -40,7 +30,7 @@ describe AviGlitch, 'datamosh cli' do
|
|
40
30
|
system [@cmd, '-a', @in].join(' ')
|
41
31
|
o = AviGlitch.open @out
|
42
32
|
o.frames.size.should == total
|
43
|
-
o.frames.
|
33
|
+
o.frames[first_keyframe].is_keyframe?.should be false
|
44
34
|
o.has_keyframe?.should be false
|
45
35
|
o.close
|
46
36
|
AviGlitch::Base.surely_formatted?(@out, true).should be true
|
@@ -48,7 +38,7 @@ describe AviGlitch, 'datamosh cli' do
|
|
48
38
|
system [@cmd, @in, @in, @in].join(' ')
|
49
39
|
o = AviGlitch.open @out
|
50
40
|
o.frames.size.should == total * 3
|
51
|
-
o.frames.
|
41
|
+
o.frames[first_keyframe].is_keyframe?.should be true
|
52
42
|
o.close
|
53
43
|
AviGlitch::Base.surely_formatted?(@out, true).should be true
|
54
44
|
|
data/spec/frames_spec.rb
CHANGED
@@ -5,26 +5,21 @@ describe AviGlitch::Frames do
|
|
5
5
|
before :all do
|
6
6
|
AviGlitch::Frames.class_eval do
|
7
7
|
define_method(:get_real_id_with) do |frame|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
movi = @avi.get_movi
|
9
|
+
pos = movi.pos
|
10
|
+
movi.pos -= frame.data.size
|
11
|
+
movi.pos -= 8
|
12
|
+
id = movi.read 4
|
13
|
+
movi.pos = pos
|
13
14
|
id
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
after :each do
|
23
|
-
FileUtils.rm Dir.glob((OUTPUT_DIR + '*').to_s)
|
24
|
-
end
|
25
|
-
|
26
|
-
after :all do
|
27
|
-
FileUtils.rmdir OUTPUT_DIR
|
18
|
+
AviGlitch::Avi.class_eval do
|
19
|
+
define_method(:get_movi) do
|
20
|
+
@movi
|
21
|
+
end
|
22
|
+
end
|
28
23
|
end
|
29
24
|
|
30
25
|
it 'should save the same file when nothing is changed' do
|
@@ -85,15 +80,6 @@ describe AviGlitch::Frames do
|
|
85
80
|
avi.close
|
86
81
|
end
|
87
82
|
|
88
|
-
it 'should hide the inner variables' do
|
89
|
-
avi = AviGlitch.open @in
|
90
|
-
frames = avi.frames
|
91
|
-
lambda { frames.meta }.should raise_error(NoMethodError)
|
92
|
-
lambda { frames.io }.should raise_error(NoMethodError)
|
93
|
-
lambda { frames.frames_data_as_io }.should raise_error(NoMethodError)
|
94
|
-
avi.close
|
95
|
-
end
|
96
|
-
|
97
83
|
it 'should save video frames count in header' do
|
98
84
|
avi = AviGlitch.open @in
|
99
85
|
c = 0
|
@@ -557,4 +543,27 @@ describe AviGlitch::Frames do
|
|
557
543
|
expect(ac2).to eq(ac)
|
558
544
|
end
|
559
545
|
|
546
|
+
it 'should pick the first / last frame with a method' do
|
547
|
+
a = AviGlitch.open @in
|
548
|
+
fkidx = -1
|
549
|
+
lkidx = -1
|
550
|
+
faidx = -1
|
551
|
+
laidx = -1
|
552
|
+
a.frames.each_with_index do |f, i|
|
553
|
+
if f.is_keyframe?
|
554
|
+
fkidx = i if fkidx == -1
|
555
|
+
lkidx = i
|
556
|
+
end
|
557
|
+
if f.is_audioframe?
|
558
|
+
faidx = i if faidx == -1
|
559
|
+
laidx = i
|
560
|
+
end
|
561
|
+
end
|
562
|
+
a.frames.index(a.frames.first_of(:keyframe)).should eq(fkidx)
|
563
|
+
a.frames.rindex(a.frames.last_of(:keyframe)).should eq(lkidx)
|
564
|
+
a.frames.index(a.frames.first_of(:audioframe)).should eq(faidx)
|
565
|
+
a.frames.rindex(a.frames.last_of(:audioframe)).should eq(laidx)
|
566
|
+
a.close
|
567
|
+
end
|
568
|
+
|
560
569
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rspec'
|
|
2
2
|
require 'aviglitch'
|
3
3
|
require 'pathname'
|
4
4
|
require 'fileutils'
|
5
|
+
require 'net/http'
|
5
6
|
|
6
7
|
FILES_DIR = Pathname.new(File.dirname(__FILE__)).realpath + 'files'
|
7
8
|
OUTPUT_DIR = FILES_DIR + 'output'
|
@@ -11,4 +12,44 @@ RSpec.configure do |config|
|
|
11
12
|
config.expect_with :rspec do |c|
|
12
13
|
c.syntax = [:should, :expect]
|
13
14
|
end
|
15
|
+
|
16
|
+
config.before(:all) do
|
17
|
+
FileUtils.mkdir FILES_DIR unless File.exist? FILES_DIR
|
18
|
+
FileUtils.mkdir OUTPUT_DIR unless File.exist? OUTPUT_DIR
|
19
|
+
@in = FILES_DIR + 'sample1.avi'
|
20
|
+
@in2 = FILES_DIR + 'sample2.avi'
|
21
|
+
@out = OUTPUT_DIR + 'out.avi'
|
22
|
+
[
|
23
|
+
[@in2, 'http://a.ucnv.org/sample2.avi'], [@in, 'http://a.ucnv.org/sample1.avi']
|
24
|
+
].each do |file, url|
|
25
|
+
unless File.exist? file
|
26
|
+
if file == @in2
|
27
|
+
puts 'At first test it needs to download a file over 1GB. It will take a while.'
|
28
|
+
end
|
29
|
+
puts 'Downloading ' + url
|
30
|
+
$stdout.sync = true
|
31
|
+
u = URI.parse url
|
32
|
+
Net::HTTP.start(u.host, u.port) do |http|
|
33
|
+
res = http.request_head u.path
|
34
|
+
max = res['content-length'].to_i
|
35
|
+
len = 0
|
36
|
+
bl = 75
|
37
|
+
File.open(file, 'w') do |file|
|
38
|
+
http.get(u.path) do |chunk|
|
39
|
+
file.write chunk
|
40
|
+
len += chunk.length
|
41
|
+
pct = '%3.1f' % (100.0 * len / max)
|
42
|
+
bar = ('#' * (bl * len / max)).ljust(bl)
|
43
|
+
print "\r#{bar} #{'%5s' % pct}%" unless ENV['CI']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
puts
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
config.after(:each) do
|
53
|
+
FileUtils.rm Dir.glob((OUTPUT_DIR + '*').to_s)
|
54
|
+
end
|
14
55
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aviglitch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ucnv
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -73,15 +73,16 @@ files:
|
|
73
73
|
- aviglitch.gemspec
|
74
74
|
- bin/datamosh
|
75
75
|
- lib/aviglitch.rb
|
76
|
+
- lib/aviglitch/avi.rb
|
76
77
|
- lib/aviglitch/base.rb
|
77
78
|
- lib/aviglitch/frame.rb
|
78
79
|
- lib/aviglitch/frames.rb
|
80
|
+
- spec/avi2_spec.rb
|
79
81
|
- spec/aviglitch_spec.rb
|
80
82
|
- spec/datamosh_spec.rb
|
81
|
-
- spec/files/sample.avi
|
82
83
|
- spec/frames_spec.rb
|
83
84
|
- spec/spec_helper.rb
|
84
|
-
homepage:
|
85
|
+
homepage: https://github.com/ucnv/aviglitch
|
85
86
|
licenses:
|
86
87
|
- MIT
|
87
88
|
metadata: {}
|
@@ -107,8 +108,8 @@ signing_key:
|
|
107
108
|
specification_version: 4
|
108
109
|
summary: A Ruby library to destroy your AVI files.
|
109
110
|
test_files:
|
111
|
+
- spec/avi2_spec.rb
|
110
112
|
- spec/aviglitch_spec.rb
|
111
113
|
- spec/datamosh_spec.rb
|
112
|
-
- spec/files/sample.avi
|
113
114
|
- spec/frames_spec.rb
|
114
115
|
- spec/spec_helper.rb
|
data/spec/files/sample.avi
DELETED
Binary file
|