aviglitch 0.1.2 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 67b4c434f616f3731fd09f5b0d0263e634cc87148e8fad42dd38e6b4d554222a
4
+ data.tar.gz: a61ad04a958aec548dec7b554ec8f1b24ff5973d4fa76862dc0ca067fccbeb11
5
+ SHA512:
6
+ metadata.gz: 20b11703e84322c798b7a450508d9848f0dd25534ff9bbf3395b269dd8959a454ad805d013dfcb3cdffadccd2c120b8a4912e1356cfa9079c7a3791284fa9bad
7
+ data.tar.gz: 9c5dd3b8c13a186a59b5fd4ad97c992e24c2967dd4629d86b1c6678c0b2fd07ad66a9711175dc499ec6e83893caa464fce2fa374e60d6daf79b47063e3fcf039
@@ -0,0 +1,35 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: test
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7', '3.0']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
+ # uses: ruby/setup-ruby@v1
30
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
34
+ - name: Run tests
35
+ run: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ doc
6
+ pkg
7
+ tmp
8
+ *.gem
9
+ Gemfile.lock
10
+ Guardfile
11
+ .yardoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ -c
2
+ --format documentation
data/ChangeLog.md ADDED
@@ -0,0 +1,59 @@
1
+ ### 0.1.6 / 2021-08-21
2
+
3
+ * Removed obsolete dependencies.
4
+
5
+ ### 0.1.5 / 2014-12-12
6
+
7
+ * Fix Frames#concat and two other method to return self.
8
+ * Some internal changes.
9
+
10
+ ### 0.1.4 / 2014-04-10
11
+
12
+ * Added an enumerator style on AviGlitch::Base#glitch and
13
+ AviGlitch::Frames#each
14
+ * Added AviGlitch::Base#remove_all_keyframes!
15
+ * Renamed #clear_keyframes! to #mutate_keyframes_into_deltaframes!
16
+ * Improved the processing speed in some measure.
17
+ * Some minor fixes.
18
+
19
+ ### 0.1.3 / 2011-08-19
20
+
21
+ * Added has_keyframe? method to AviGlitch::Base
22
+ * Added a --fake option to datamosh cli.
23
+
24
+ ### 0.1.2 / 2011-04-10
25
+
26
+ * Fix to be able to handle data with offsets from 0 of the file.
27
+ * Added clear_keyframes! method to AviGlitch::Frames and AviGlitch::Base.
28
+ * Changed to be able to access frame's meta data.
29
+ * Changed datamosh command to handle wildcard char.
30
+
31
+ ### 0.1.1 / 2010-09-09
32
+
33
+ * Fixed a bug with windows.
34
+ * Some tiny fixes.
35
+
36
+ ### 0.1.0 / 2010-07-09
37
+
38
+ * Minor version up.
39
+ * Fixed bugs with Ruby 1.8.7.
40
+ * Fixed the synchronization problem with datamosh cli.
41
+
42
+ ### 0.0.3 / 2010-07-07
43
+
44
+ * Changed AviGlitch::Frames allowing to slice and concatenate frames
45
+ (like Array).
46
+ * Changed datamosh cli to accept multiple files.
47
+
48
+ ### 0.0.2 / 2010-05-17
49
+
50
+ * Removed AviGlitch#new. Use AviGlitch#open instead of #new.
51
+ * Added warning for a large file.
52
+ * Changed datamosh command interface.
53
+ * Changed the library file layout.
54
+ * And tiny internal changes.
55
+
56
+ ### 0.0.1 / 2009-08-01
57
+
58
+ * initial release
59
+
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 ucnv
1
+ Copyright (c) 2009-2021 ucnv
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # AviGlitch
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/aviglitch.svg)](https://badge.fury.io/rb/aviglitch)
4
+ [![test](https://github.com/ucnv/aviglitch/actions/workflows/ruby.yml/badge.svg)](https://github.com/ucnv/aviglitch/actions/workflows/ruby.yml)
5
+
6
+ AviGlitch destroys your AVI files.
7
+
8
+ I can't explain why they're going to destroy their own data, but they do.
9
+
10
+ You can find a short guide at <https://ucnv.github.io/aviglitch/>.
11
+ It provides a way to manipulate the data in each AVI frames.
12
+ It will mostly be used for making datamoshing videos.
13
+ It parses only container level structure, doesn't parse codecs.
14
+
15
+ See following urls for details about visual glitch;
16
+
17
+ * vimeo <http://www.vimeo.com/groups/artifacts>
18
+ * wikipedia <http://en.wikipedia.org/wiki/Compression_artifact>
19
+
20
+ ## Usage
21
+
22
+ ```ruby
23
+ require 'aviglitch'
24
+
25
+ avi = AviGlitch.open('/path/to/your.avi')
26
+ avi.glitch(:keyframe) do |data|
27
+ data.gsub(/\d/, '0')
28
+ end
29
+ avi.output('/path/to/broken.avi')
30
+ ```
31
+
32
+ This library also includes a command line tool named `datamosh`.
33
+ It creates the keyframes removed video.
34
+
35
+ ```sh
36
+ $ datamosh /path/to/your.avi -o /path/to/broken.avi
37
+ ```
38
+
39
+ For more practical usages, please check <https://github.com/ucnv/aviglitch-utils/tree/master/bin>.
40
+
41
+ ## Installation
42
+
43
+ ```sh
44
+ gem install aviglitch
45
+ ```
46
+
47
+ ## Known issues
48
+
49
+ - This library doesn't support AVI2 format spec. This means that it will not work as expected for files larger than 1GB.
50
+
51
+ ## License
52
+
53
+ This library is distributed under the terms and conditions of the [MIT license](LICENSE).
data/Rakefile CHANGED
@@ -1,50 +1,13 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "aviglitch"
8
- gem.summary = "A Ruby library to destroy your AVI files."
9
- gem.email = "ucnvvv@gmail.com"
10
- gem.homepage = "http://ucnv.github.com/aviglitch/"
11
- gem.authors = ["ucnv"]
12
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
- gem.files = %w(README.rdoc ChangeLog Rakefile VERSION) +
14
- Dir.glob("{bin,spec,lib}/**/*")
15
- gem.add_development_dependency "rspec", ">= 2.0.0"
16
-
17
- end
18
-
19
- rescue LoadError
20
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
21
- end
22
-
23
- require 'rspec/core/rake_task'
24
- RSpec::Core::RakeTask.new(:spec) do |spec|
25
- spec.pattern = FileList['spec/**/*_spec.rb']
26
- end
27
-
28
- RSpec::Core::RakeTask.new(:rcov) do |spec|
29
- spec.pattern = 'spec/**/*_spec.rb'
30
- spec.rcov = true
31
- end
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
32
3
 
4
+ RSpec::Core::RakeTask.new(:spec)
33
5
 
34
6
  task :default => :spec
35
7
 
36
- require 'rake/rdoctask'
8
+ require 'rdoc/task'
37
9
  Rake::RDocTask.new do |rdoc|
38
- if File.exist?('VERSION.yml')
39
- config = YAML.load(File.read('VERSION.yml'))
40
- version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
41
- else
42
- version = ""
43
- end
44
-
10
+ rdoc.main = "README.md"
45
11
  rdoc.rdoc_dir = 'rdoc'
46
- rdoc.title = "aviglitch #{version}"
47
- rdoc.rdoc_files.include('README*')
48
- rdoc.rdoc_files.include('lib/**/*.rb')
12
+ rdoc.rdoc_files.include(%w{LICENSE *.md lib/**/*.rb})
49
13
  end
50
-
data/aviglitch.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aviglitch'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aviglitch"
8
+ spec.version = AviGlitch::VERSION
9
+ spec.authors = ["ucnv"]
10
+ spec.email = ["ucnvvv@gmail.com"]
11
+ spec.summary = %q{A Ruby library to destroy your AVI files.}
12
+ spec.description = spec.summary
13
+ spec.homepage = "http://ucnv.github.com/aviglitch/"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.has_rdoc = true
22
+ spec.extra_rdoc_files = ["README.md", "LICENSE"]
23
+ spec.rdoc_options << "-m" << "README.md"
24
+
25
+ spec.add_development_dependency "bundler", ">= 2.2.10"
26
+ spec.add_development_dependency "rake", ">= 12.3.3"
27
+ spec.add_development_dependency "rspec"
28
+ end
data/bin/datamosh CHANGED
@@ -7,6 +7,7 @@ require 'aviglitch'
7
7
 
8
8
  output = './out.avi'
9
9
  all = false
10
+ fake = false
10
11
 
11
12
  opts = OptionParser.new do |opts|
12
13
  opts.banner = "datamosh - AviGlitch's datamoshing video generator."
@@ -20,30 +21,49 @@ opts = OptionParser.new do |opts|
20
21
  "Remove all keyframes (It remains a first keyframe by default)") do
21
22
  all = true
22
23
  end
24
+ opts.on("--fake", "Remains all keyframes as full pixel included deltaframe") do
25
+ fake = true
26
+ if all
27
+ warn "The --fake option cannot use with -a/--all option.\n"
28
+ exit
29
+ end
30
+ end
23
31
  opts.on_tail("-h", "--help", "Show this message") do
24
32
  puts opts
25
33
  exit
26
34
  end
27
35
  end
28
36
 
29
- input = Dir.glob opts.parse!
37
+ input = opts.parse!
30
38
  if input.empty?
31
39
  puts opts
32
40
  exit 1
41
+ else
42
+ input.each do |file|
43
+ if !File.exist?(file) || File.directory?(file)
44
+ opts.banner = "#{file}: No such file.\n\n"
45
+ puts opts
46
+ exit 1
47
+ end
48
+ end
33
49
  end
34
50
 
35
51
  a = AviGlitch.open input.shift
36
- a.glitch_with_index :keyframe do |frame, i|
37
- (!all && i == 0) ? frame : "" # keep the first frame
52
+ unless fake
53
+ a.glitch_with_index :keyframe do |frame, i|
54
+ (!all && i == 0) ? frame : "" # keep the first frame
55
+ end
38
56
  end
39
- a.clear_keyframes!(!all ? 1..a.frames.size : nil)
57
+ a.mutate_keyframes_into_deltaframes!(!all && !fake ? 1..a.frames.size : nil)
40
58
 
41
59
  input.each do |file|
42
60
  b = AviGlitch.open file
43
- b.glitch :keyframe do |frame|
44
- ""
61
+ unless fake
62
+ b.glitch :keyframe do |frame|
63
+ ""
64
+ end
45
65
  end
46
- b.clear_keyframes!
66
+ b.mutate_keyframes_into_deltaframes!
47
67
  a.frames.concat b.frames
48
68
  end
49
69
 
data/lib/aviglitch.rb CHANGED
@@ -6,7 +6,6 @@ require 'stringio'
6
6
  require 'aviglitch/base'
7
7
  require 'aviglitch/frame'
8
8
  require 'aviglitch/frames'
9
- require 'aviglitch/tempfile'
10
9
 
11
10
  # AviGlitch provides the ways to glitch AVI formatted video files.
12
11
  #
@@ -15,7 +14,7 @@ require 'aviglitch/tempfile'
15
14
  # You can manipulate each frame, like:
16
15
  #
17
16
  # avi = AviGlitch.open '/path/to/your.avi'
18
- # avi.frames.each |frame|
17
+ # avi.frames.each do |frame|
19
18
  # if frame.is_keyframe?
20
19
  # frame.data = frame.data.gsub(/\d/, '0')
21
20
  # end
@@ -30,18 +29,17 @@ require 'aviglitch/tempfile'
30
29
  # end
31
30
  # avi.output '/path/to/broken.avi'
32
31
  #
33
- #--
34
- # It does not support AVI2, interleave format.
35
- #
36
32
  module AviGlitch
37
33
 
38
- VERSION = '0.1.2'
34
+ VERSION = '0.1.6'
35
+
36
+ BUFFER_SIZE = 2 ** 24
39
37
 
40
38
  class << self
41
39
  ##
42
40
  # Returns AviGlitch::Base instance.
43
41
  # It requires +path_or_frames+ as String or Pathname, or Frames instance.
44
- def AviGlitch.open path_or_frames
42
+ def open path_or_frames
45
43
  if path_or_frames.kind_of?(Frames)
46
44
  path_or_frames.to_avi
47
45
  else
@@ -17,9 +17,9 @@ module AviGlitch
17
17
  def initialize path
18
18
  File.open(path, 'rb') do |f|
19
19
  # copy as tempfile
20
- @file = Tempfile.open 'aviglitch'
20
+ @file = Tempfile.new 'aviglitch', binmode: true
21
21
  f.rewind
22
- while d = f.read(1024) do
22
+ while d = f.read(BUFFER_SIZE) do
23
23
  @file.print d
24
24
  end
25
25
  end
@@ -28,7 +28,6 @@ module AviGlitch
28
28
  raise 'Unsupported file passed.'
29
29
  end
30
30
  @frames = Frames.new @file
31
- # I believe Ruby's GC to close and remove the Tempfile..
32
31
  end
33
32
 
34
33
  ##
@@ -59,34 +58,61 @@ module AviGlitch
59
58
  # It also requires a block. In the block, you take the frame data
60
59
  # as a String parameter.
61
60
  # To modify the data, simply return a modified data.
62
- # It returns +self+
61
+ # Without a block it returns Enumerator, with a block it returns +self+.
63
62
  def glitch target = :all, &block # :yield: data
64
- @frames.each do |frame|
65
- if valid_target? target, frame
66
- frame.data = yield frame.data
63
+ if block_given?
64
+ @frames.each do |frame|
65
+ if valid_target? target, frame
66
+ frame.data = yield frame.data
67
+ end
67
68
  end
69
+ self
70
+ else
71
+ self.enum_for :glitch, target
68
72
  end
69
- self
70
73
  end
71
74
 
72
75
  ##
73
76
  # Do glitch with index.
74
77
  def glitch_with_index target = :all, &block # :yield: data, index
75
- i = 0
76
- @frames.each do |frame|
77
- if valid_target? target, frame
78
- frame.data = yield(frame.data, i)
79
- i += 1
78
+ if block_given?
79
+ self.glitch(target).with_index do |x, i|
80
+ yield x, i
80
81
  end
82
+ self
83
+ else
84
+ self.glitch target
81
85
  end
86
+ end
87
+
88
+ ##
89
+ # Mutates all (or in +range+) keyframes into deltaframes.
90
+ # It's an alias for Frames#mutate_keyframes_into_deltaframes!
91
+ def mutate_keyframes_into_deltaframes! range = nil
92
+ self.frames.mutate_keyframes_into_deltaframes! range
82
93
  self
83
94
  end
84
95
 
85
96
  ##
86
- # Clears all (or in +range+) keyframes to deltaframes.
87
- # It's an alias for Frames#clear_keyframes!
88
- def clear_keyframes! range = nil
89
- self.frames.clear_keyframes! range
97
+ # Check if it has keyframes.
98
+ def has_keyframe?
99
+ result = false
100
+ self.frames.each do |f|
101
+ if f.is_keyframe?
102
+ result = true
103
+ break
104
+ end
105
+ end
106
+ result
107
+ end
108
+
109
+ ##
110
+ # Removes all keyframes.
111
+ # It is same as +glitch(:keyframes){|f| nil }+
112
+ def remove_all_keyframes!
113
+ self.glitch :keyframe do |f|
114
+ nil
115
+ end
90
116
  self
91
117
  end
92
118
 
@@ -99,6 +125,7 @@ module AviGlitch
99
125
  end
100
126
 
101
127
  alias_method :write, :output
128
+ alias_method :has_keyframes?, :has_keyframe?
102
129
 
103
130
  def valid_target? target, frame #:nodoc:
104
131
  return true if target == :all
@@ -120,8 +147,6 @@ module AviGlitch
120
147
  is_io = file.respond_to?(:seek) # Probably IO.
121
148
  file = File.open(file, 'rb') unless is_io
122
149
  begin
123
- file.seek 0, IO::SEEK_END
124
- eof = file.pos
125
150
  file.rewind
126
151
  unless file.read(4) == 'RIFF'
127
152
  answer = false
@@ -18,8 +18,13 @@ module AviGlitch
18
18
  class Frames
19
19
  include Enumerable
20
20
 
21
- SAFE_FRAMES_COUNT = 150000 #:nodoc:
22
- @@warn_if_frames_are_too_large = true #:nodoc:
21
+ # :stopdoc:
22
+
23
+ ##
24
+ SAFE_FRAMES_COUNT = 150000
25
+ @@warn_if_frames_are_too_large = true
26
+
27
+ # :startdoc:
23
28
 
24
29
  attr_reader :meta
25
30
 
@@ -56,11 +61,16 @@ module AviGlitch
56
61
 
57
62
  ##
58
63
  # Enumerates the frames.
59
- def each
60
- temp = Tempfile.new 'frames'
61
- frames_data_as_io(temp, Proc.new)
62
- overwrite temp
63
- temp.close!
64
+ # It returns Enumerator if a block is not given.
65
+ def each &block
66
+ if block_given?
67
+ temp = Tempfile.new 'frames', binmode: true
68
+ frames_data_as_io(temp, block)
69
+ overwrite temp
70
+ temp.close!
71
+ else
72
+ self.enum_for :each
73
+ end
64
74
  end
65
75
 
66
76
  ##
@@ -69,8 +79,17 @@ module AviGlitch
69
79
  @meta.size
70
80
  end
71
81
 
82
+ ##
83
+ # Returns the number of the specific +frame_type+.
84
+ def size_of frame_type
85
+ detection = "is_#{frame_type.to_s.sub(/frames$/, 'frame')}?"
86
+ @meta.select { |m|
87
+ Frame.new(nil, m[:id], m[:flag]).send detection
88
+ }.size
89
+ end
90
+
72
91
  def frames_data_as_io io = nil, block = nil #:nodoc:
73
- io = Tempfile.new('tmep') if io.nil?
92
+ io = Tempfile.new('tmep', binmode: true) if io.nil?
74
93
  @meta = @meta.select do |m|
75
94
  @io.pos = @pos_of_movi + m[:offset] + 8 # 8 for id and size
76
95
  frame = Frame.new(@io.read(m[:size]), m[:id], m[:flag])
@@ -99,20 +118,19 @@ module AviGlitch
99
118
  exit
100
119
  end
101
120
  # Overwrite the file
102
- data.seek 0, IO::SEEK_END
103
121
  @io.pos = @pos_of_movi - 4 # 4 for size
104
122
  @io.print [data.pos + 4].pack('V') # 4 for 'movi'
105
123
  @io.print 'movi'
106
124
  data.rewind
107
- while d = data.read(1024) do
125
+ while d = data.read(BUFFER_SIZE) do
108
126
  @io.print d
109
127
  end
110
128
  @io.print 'idx1'
111
129
  @io.print [@meta.size * 16].pack('V')
112
- @meta.each do |m|
113
- @io.print m[:id]
114
- @io.print [m[:flag], m[:offset], m[:size]].pack('V3')
115
- end
130
+ idx = @meta.collect { |m|
131
+ m[:id] + [m[:flag], m[:offset], m[:size]].pack('V3')
132
+ }.join
133
+ @io.print idx
116
134
  eof = @io.pos
117
135
  @io.truncate eof
118
136
 
@@ -145,14 +163,13 @@ module AviGlitch
145
163
  def concat other_frames
146
164
  raise TypeError unless other_frames.kind_of?(Frames)
147
165
  # data
148
- this_data = Tempfile.new 'this'
166
+ this_data = Tempfile.new 'this', binmode: true
149
167
  self.frames_data_as_io this_data
150
- other_data = Tempfile.new 'other'
168
+ other_data = Tempfile.new 'other', binmode: true
151
169
  other_frames.frames_data_as_io other_data
152
- this_data.seek 0, IO::SEEK_END
153
- this_size = this_data.pos
170
+ this_size = this_data.size
154
171
  other_data.rewind
155
- while d = other_data.read(1024) do
172
+ while d = other_data.read(BUFFER_SIZE) do
156
173
  this_data.print d
157
174
  end
158
175
  other_data.close!
@@ -166,6 +183,7 @@ module AviGlitch
166
183
  # close
167
184
  overwrite this_data
168
185
  this_data.close!
186
+ self
169
187
  end
170
188
 
171
189
  ##
@@ -278,10 +296,9 @@ module AviGlitch
278
296
  def push frame
279
297
  raise TypeError unless frame.kind_of? Frame
280
298
  # data
281
- this_data = Tempfile.new 'this'
299
+ this_data = Tempfile.new 'this', binmode: true
282
300
  self.frames_data_as_io this_data
283
- this_data.seek 0, IO::SEEK_END
284
- this_size = this_data.pos
301
+ this_size = this_data.size
285
302
  this_data.print frame.id
286
303
  this_data.print [frame.data.size].pack('V')
287
304
  this_data.print frame.data
@@ -324,14 +341,15 @@ module AviGlitch
324
341
  end
325
342
 
326
343
  ##
327
- # Modify keyframes to deltaframes at given range, or all.
328
- def clear_keyframes! range = nil
344
+ # Mutates keyframes into deltaframes at given range, or all.
345
+ def mutate_keyframes_into_deltaframes! range = nil
329
346
  range = 0..self.size if range.nil?
330
347
  self.each_with_index do |frame, i|
331
348
  if range.include? i
332
349
  frame.flag = 0 if frame.is_keyframe?
333
350
  end
334
351
  end
352
+ self
335
353
  end
336
354
 
337
355
  ##
@@ -52,13 +52,24 @@ describe AviGlitch do
52
52
 
53
53
  it 'can glitch each keyframe with index' do
54
54
  avi = AviGlitch.open @in
55
+
56
+ a_size = 0
57
+ avi.glitch :keyframe do |f|
58
+ a_size += 1
59
+ f
60
+ end
61
+
62
+ b_size = 0
55
63
  avi.glitch_with_index :keyframe do |kf, idx|
64
+ b_size += 1
56
65
  if idx < 25
57
66
  kf.slice(10..kf.size)
58
67
  else
59
68
  kf
60
69
  end
61
70
  end
71
+ expect(a_size).to be == b_size
72
+
62
73
  avi.output @out
63
74
  i_size = File.stat(@in).size
64
75
  o_size = File.stat(@out).size
@@ -143,9 +154,9 @@ describe AviGlitch do
143
154
  AviGlitch::Base.surely_formatted?(@out, true).should be true
144
155
  end
145
156
 
146
- it 'should clear keyframes with one method' do
157
+ it 'should mutate keyframes into deltaframes' do
147
158
  a = AviGlitch.open @in
148
- a.clear_keyframes!
159
+ a.mutate_keyframes_into_deltaframes!
149
160
  a.output @out
150
161
  a = AviGlitch.open @out
151
162
  a.frames.each do |f|
@@ -153,7 +164,7 @@ describe AviGlitch do
153
164
  end
154
165
 
155
166
  a = AviGlitch.open @in
156
- a.clear_keyframes! 0..50
167
+ a.mutate_keyframes_into_deltaframes! 0..50
157
168
  a.output @out
158
169
  a = AviGlitch.open @out
159
170
  a.frames.each_with_index do |f, i|
@@ -163,4 +174,38 @@ describe AviGlitch do
163
174
  end
164
175
  end
165
176
 
177
+ it 'should check if keyframes exist.' do
178
+ a = AviGlitch.open @in
179
+ a.has_keyframe?.should be true
180
+ a.glitch :keyframe do |f|
181
+ nil
182
+ end
183
+ a.has_keyframe?.should be false
184
+ end
185
+
186
+ it 'should #remove_all_keyframes!' do
187
+ a = AviGlitch.open @in
188
+ a.has_keyframe?.should be true
189
+ a.remove_all_keyframes!
190
+ a.has_keyframe?.should be false
191
+ end
192
+
193
+ it 'should count same number of specific frames' do
194
+ a = AviGlitch.open @in
195
+ dc1 = 0
196
+ dc2 = 0
197
+ a.frames.each do |f|
198
+ dc1 += 1 if f.is_deltaframe?
199
+ end
200
+ a.glitch(:deltaframe) do |d|
201
+ dc2 += 1
202
+ d
203
+ end
204
+
205
+ expect(dc1).to eq(dc2)
206
+
207
+
208
+
209
+ end
210
+
166
211
  end
@@ -33,6 +33,7 @@ describe AviGlitch, 'datamosh cli' do
33
33
  o = AviGlitch.open @out
34
34
  o.frames.size.should == total
35
35
  o.frames.first.is_keyframe?.should be true
36
+ o.has_keyframe?.should be true
36
37
  o.close
37
38
  AviGlitch::Base.surely_formatted?(@out, true).should be true
38
39
 
@@ -40,6 +41,7 @@ describe AviGlitch, 'datamosh cli' do
40
41
  o = AviGlitch.open @out
41
42
  o.frames.size.should == total
42
43
  o.frames.first.is_keyframe?.should be false
44
+ o.has_keyframe?.should be false
43
45
  o.close
44
46
  AviGlitch::Base.surely_formatted?(@out, true).should be true
45
47
 
@@ -49,6 +51,11 @@ describe AviGlitch, 'datamosh cli' do
49
51
  o.frames.first.is_keyframe?.should be true
50
52
  o.close
51
53
  AviGlitch::Base.surely_formatted?(@out, true).should be true
52
- end
53
54
 
55
+ system [@cmd, '--fake', @in].join(' ')
56
+ o = AviGlitch.open @out
57
+ o.has_keyframe?.should be false
58
+ o.close
59
+
60
+ end
54
61
  end
data/spec/frames_spec.rb CHANGED
@@ -460,9 +460,9 @@ describe AviGlitch::Frames do
460
460
  end
461
461
  end
462
462
 
463
- it 'should clear keyframes with one method' do
463
+ it 'should mutate keyframes into deltaframe' do
464
464
  a = AviGlitch.open @in
465
- a.frames.clear_keyframes!
465
+ a.frames.mutate_keyframes_into_deltaframes!
466
466
  a.output @out
467
467
  a = AviGlitch.open @out
468
468
  a.frames.each do |f|
@@ -470,7 +470,7 @@ describe AviGlitch::Frames do
470
470
  end
471
471
 
472
472
  a = AviGlitch.open @in
473
- a.frames.clear_keyframes! 0..50
473
+ a.frames.mutate_keyframes_into_deltaframes! 0..50
474
474
  a.output @out
475
475
  a = AviGlitch.open @out
476
476
  a.frames.each_with_index do |f, i|
@@ -480,4 +480,81 @@ describe AviGlitch::Frames do
480
480
  end
481
481
  end
482
482
 
483
+ it 'should return Enumerator with #each' do
484
+ a = AviGlitch.open @in
485
+ enum = a.frames.each
486
+ enum.each do |f, i|
487
+ if f.is_keyframe?
488
+ f.data = f.data.gsub(/\d/, '')
489
+ end
490
+ end
491
+ a.output @out
492
+ AviGlitch::Base.surely_formatted?(@out, true).should be true
493
+ expect(File.size(@out)).to be < File.size(@in)
494
+ end
495
+
496
+ it 'should use Enumerator as an external iterator',
497
+ :skip => Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('1.9.0') || RUBY_PLATFORM == 'java' do
498
+ a = AviGlitch.open @in
499
+ e = a.frames.each
500
+ expect {
501
+ while f = e.next do
502
+ expect(f).to be_a(AviGlitch::Frame)
503
+ if f.is_keyframe?
504
+ f.data = f.data.gsub(/\d/, '')
505
+ end
506
+ end
507
+ }.to raise_error(StopIteration)
508
+ a.output @out
509
+ AviGlitch::Base.surely_formatted?(@out, true).should be true
510
+ expect(File.size(@out)).to be < File.size(@in)
511
+ end
512
+
513
+ it 'should count the size of specific frames' do
514
+ a = AviGlitch.open @in
515
+ f = a.frames
516
+
517
+ kc1 = f.size_of :keyframes
518
+ kc2 = f.size_of :keyframe
519
+ kc3 = f.size_of :iframes
520
+ kc4 = f.size_of :iframe
521
+
522
+ dc1 = f.size_of :deltaframes
523
+ dc2 = f.size_of :deltaframe
524
+ dc3 = f.size_of :pframes
525
+ dc4 = f.size_of :pframe
526
+
527
+ vc1 = f.size_of :videoframes
528
+ vc2 = f.size_of :videoframe
529
+
530
+ ac1 = f.size_of :audioframes
531
+ ac2 = f.size_of :audioframe
532
+
533
+ kc = dc = vc = ac = 0
534
+ a.frames.each do |x|
535
+ vc += x.is_videoframe? ? 1 : 0
536
+ kc += x.is_keyframe? ? 1 : 0
537
+ dc += x.is_deltaframe? ? 1 : 0
538
+ ac += x.is_audioframe? ? 1 : 0
539
+ end
540
+
541
+ a.close
542
+
543
+ expect(kc1).to eq(kc)
544
+ expect(kc2).to eq(kc)
545
+ expect(kc3).to eq(kc)
546
+ expect(kc4).to eq(kc)
547
+
548
+ expect(dc1).to eq(dc)
549
+ expect(dc2).to eq(dc)
550
+ expect(dc3).to eq(dc)
551
+ expect(dc4).to eq(dc)
552
+
553
+ expect(vc1).to eq(vc)
554
+ expect(vc2).to eq(vc)
555
+
556
+ expect(ac1).to eq(ac)
557
+ expect(ac2).to eq(ac)
558
+ end
559
+
483
560
  end
data/spec/spec_helper.rb CHANGED
@@ -7,5 +7,8 @@ FILES_DIR = Pathname.new(File.dirname(__FILE__)).realpath + 'files'
7
7
  OUTPUT_DIR = FILES_DIR + 'output'
8
8
 
9
9
  RSpec.configure do |config|
10
-
10
+ config.filter_run_excluding :skip => true
11
+ config.expect_with :rspec do |c|
12
+ c.syntax = [:should, :expect]
13
+ end
11
14
  end
metadata CHANGED
@@ -1,98 +1,114 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: aviglitch
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 2
9
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.6
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - ucnv
13
- autorequire:
8
+ autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2011-04-10 00:00:00 +09:00
18
- default_executable: datamosh
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: rspec
11
+ date: 2021-08-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.2.10
20
+ type: :development
22
21
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
26
24
  - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 2
30
- - 0
31
- - 0
32
- version: 2.0.0
25
+ - !ruby/object:Gem::Version
26
+ version: 2.2.10
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 12.3.3
33
34
  type: :development
34
- version_requirements: *id001
35
- description:
36
- email: ucnvvv@gmail.com
37
- executables:
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 12.3.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: A Ruby library to destroy your AVI files.
56
+ email:
57
+ - ucnvvv@gmail.com
58
+ executables:
38
59
  - datamosh
39
60
  extensions: []
40
-
41
- extra_rdoc_files:
42
- - ChangeLog
61
+ extra_rdoc_files:
62
+ - README.md
43
63
  - LICENSE
44
- - README.rdoc
45
- files:
46
- - ChangeLog
47
- - README.rdoc
64
+ files:
65
+ - ".github/workflows/ruby.yml"
66
+ - ".gitignore"
67
+ - ".rspec"
68
+ - ChangeLog.md
69
+ - Gemfile
70
+ - LICENSE
71
+ - README.md
48
72
  - Rakefile
49
- - VERSION
73
+ - aviglitch.gemspec
50
74
  - bin/datamosh
51
75
  - lib/aviglitch.rb
52
76
  - lib/aviglitch/base.rb
53
77
  - lib/aviglitch/frame.rb
54
78
  - lib/aviglitch/frames.rb
55
- - lib/aviglitch/tempfile.rb
56
79
  - spec/aviglitch_spec.rb
57
80
  - spec/datamosh_spec.rb
58
81
  - spec/files/sample.avi
59
82
  - spec/frames_spec.rb
60
83
  - spec/spec_helper.rb
61
- - LICENSE
62
- has_rdoc: true
63
84
  homepage: http://ucnv.github.com/aviglitch/
64
- licenses: []
65
-
66
- post_install_message:
67
- rdoc_options: []
68
-
69
- require_paths:
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options:
90
+ - "-m"
91
+ - README.md
92
+ require_paths:
70
93
  - lib
71
- required_ruby_version: !ruby/object:Gem::Requirement
72
- none: false
73
- requirements:
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
74
96
  - - ">="
75
- - !ruby/object:Gem::Version
76
- segments:
77
- - 0
78
- version: "0"
79
- required_rubygems_version: !ruby/object:Gem::Requirement
80
- none: false
81
- requirements:
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
82
101
  - - ">="
83
- - !ruby/object:Gem::Version
84
- segments:
85
- - 0
86
- version: "0"
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
87
104
  requirements: []
88
-
89
- rubyforge_project:
90
- rubygems_version: 1.3.7
91
- signing_key:
92
- specification_version: 3
105
+ rubygems_version: 3.2.22
106
+ signing_key:
107
+ specification_version: 4
93
108
  summary: A Ruby library to destroy your AVI files.
94
- test_files:
109
+ test_files:
95
110
  - spec/aviglitch_spec.rb
96
111
  - spec/datamosh_spec.rb
112
+ - spec/files/sample.avi
97
113
  - spec/frames_spec.rb
98
114
  - spec/spec_helper.rb
data/ChangeLog DELETED
@@ -1,36 +0,0 @@
1
- == 0.1.2 / 2011-04-10
2
-
3
- * Fix to be able to handle data with offsets from 0 of the file.
4
- * Added clear_keyframes! method to AviGlitch::Frames and AviGlitch::Base.
5
- * Changed to be able to access frame's meta data.
6
- * Changed datamosh command to handle wildcard char.
7
-
8
- == 0.1.1 / 2010-09-09
9
-
10
- * Fixed a bug with windows.
11
- * Some tiny fixes.
12
-
13
- == 0.1.0 / 2010-07-09
14
-
15
- * Minor version up.
16
- * Fixed bugs with Ruby 1.8.7.
17
- * Fixed the synchronization problem with datamosh cli.
18
-
19
- == 0.0.3 / 2010-07-07
20
-
21
- * Changed AviGlitch::Frames allowing to slice and concatenate frames
22
- (like Array).
23
- * Changed datamosh cli to accept multiple files.
24
-
25
- == 0.0.2 / 2010-05-17
26
-
27
- * Removed AviGlitch#new. Use AviGlitch#open instead of #new.
28
- * Added warning for a large file.
29
- * Changed datamosh command interface.
30
- * Changed the library file layout.
31
- * And tiny internal changes.
32
-
33
- == 0.0.1 / 2009-08-01
34
-
35
- * initial release
36
-
data/README.rdoc DELETED
@@ -1,42 +0,0 @@
1
- = AviGlitch
2
-
3
- * http://ucnv.github.com/aviglitch/
4
-
5
- == Description
6
-
7
- AviGlitch destroys your AVI files.
8
-
9
- I can't explain why they're going to destroy their own data.
10
-
11
- See following urls for details;
12
- * vimeo http://www.vimeo.com/groups/artifacts
13
- * wikipedia http://en.wikipedia.org/wiki/Compression_artifact
14
-
15
- == Features/Problems
16
-
17
- * Not supports AVI2 files right now.
18
- * Not supports files with interleave.
19
- * Parses only container level structure, doesn't parse codecs.
20
-
21
- == Synopsis
22
-
23
- require 'aviglitch'
24
-
25
- avi = AviGlitch.open('/path/to/your.avi')
26
- avi.glitch(:keyframe) do |data|
27
- data.gsub(/\d/, '0')
28
- end
29
- avi.output('/path/to/broken.avi')
30
-
31
- This library also includes a command line tool named +datamosh+.
32
- It creates the keyframes removed video.
33
-
34
- $ datamosh /path/to/your.avi -o /path/to/broken.avi
35
-
36
- == Installation
37
-
38
- gem install aviglitch
39
-
40
- == Copyright
41
-
42
- Copyright (c) 2009 - 2010 ucnv. See LICENSE for details.
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.2
@@ -1,8 +0,0 @@
1
- module AviGlitch
2
- class Tempfile < Tempfile
3
- def initialize *args
4
- super *args
5
- self.binmode
6
- end
7
- end
8
- end