aviglitch 0.1.2 → 0.1.6
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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/ChangeLog.md +59 -0
- data/Gemfile +2 -0
- data/LICENSE +1 -1
- data/README.md +53 -0
- data/Rakefile +6 -43
- data/aviglitch.gemspec +28 -0
- data/bin/datamosh +27 -7
- data/lib/aviglitch.rb +5 -7
- data/lib/aviglitch/base.rb +44 -19
- data/lib/aviglitch/frames.rb +42 -24
- data/spec/aviglitch_spec.rb +48 -3
- data/spec/datamosh_spec.rb +8 -1
- data/spec/frames_spec.rb +80 -3
- data/spec/spec_helper.rb +4 -1
- metadata +82 -66
- data/ChangeLog +0 -36
- data/README.rdoc +0 -42
- data/VERSION +0 -1
- data/lib/aviglitch/tempfile.rb +0 -8
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
data/.rspec
ADDED
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
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# AviGlitch
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/aviglitch)
|
4
|
+
[](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
|
2
|
-
require
|
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 '
|
8
|
+
require 'rdoc/task'
|
37
9
|
Rake::RDocTask.new do |rdoc|
|
38
|
-
|
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.
|
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 =
|
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
|
-
|
37
|
-
|
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.
|
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
|
-
|
44
|
-
|
61
|
+
unless fake
|
62
|
+
b.glitch :keyframe do |frame|
|
63
|
+
""
|
64
|
+
end
|
45
65
|
end
|
46
|
-
b.
|
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.
|
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
|
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
|
data/lib/aviglitch/base.rb
CHANGED
@@ -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.
|
20
|
+
@file = Tempfile.new 'aviglitch', binmode: true
|
21
21
|
f.rewind
|
22
|
-
while d = f.read(
|
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
|
-
#
|
61
|
+
# Without a block it returns Enumerator, with a block it returns +self+.
|
63
62
|
def glitch target = :all, &block # :yield: data
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
76
|
-
|
77
|
-
|
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
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
self.frames.
|
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
|
data/lib/aviglitch/frames.rb
CHANGED
@@ -18,8 +18,13 @@ module AviGlitch
|
|
18
18
|
class Frames
|
19
19
|
include Enumerable
|
20
20
|
|
21
|
-
|
22
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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(
|
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.
|
113
|
-
|
114
|
-
|
115
|
-
|
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.
|
153
|
-
this_size = this_data.pos
|
170
|
+
this_size = this_data.size
|
154
171
|
other_data.rewind
|
155
|
-
while d = other_data.read(
|
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.
|
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
|
-
#
|
328
|
-
def
|
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
|
##
|
data/spec/aviglitch_spec.rb
CHANGED
@@ -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
|
157
|
+
it 'should mutate keyframes into deltaframes' do
|
147
158
|
a = AviGlitch.open @in
|
148
|
-
a.
|
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.
|
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
|
data/spec/datamosh_spec.rb
CHANGED
@@ -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
|
463
|
+
it 'should mutate keyframes into deltaframe' do
|
464
464
|
a = AviGlitch.open @in
|
465
|
-
a.frames.
|
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.
|
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
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
24
|
-
|
25
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
26
24
|
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
42
|
-
- ChangeLog
|
61
|
+
extra_rdoc_files:
|
62
|
+
- README.md
|
43
63
|
- LICENSE
|
44
|
-
|
45
|
-
|
46
|
-
-
|
47
|
-
-
|
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
|
-
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
73
|
-
requirements:
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
74
96
|
- - ">="
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
85
|
-
- 0
|
86
|
-
version: "0"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
87
104
|
requirements: []
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|