AviGlitch

repository·master·Indexed 42 days ago

https://github.com/ucnv/aviglitch

A Ruby library and CLI tool for manipulating AVI file data to create datamoshing effects. It operates at the container level to target keyframes, deltaframes, and audio frames without parsing individual codecs. Includes a `datamosh` command-line utility for removing keyframes and a Ruby API for programmatic frame manipulation via the `AviGlitch` class.

Tokens
4.7K
Snippets
23
Records
29
Agent score
52%

What's inside AviGlitch

  1. Glitch AVI files using the Ruby API

    master

    You can manipulate AVI frame data programmatically using the AviGlitch class.

    1. Open an AVI file with AviGlitch.open(path).
    2. Use the glitch method, passing a symbol to specify which frames to target (e.g., :keyframe).
    3. Provide a block that receives the raw data of the frame and returns the modified data.
    4. Save the result using output(path).

    Note: The library only parses the container-level structure and does not parse codecs. It is primarily used for datamoshing.

    require 'aviglitch'
    
    avi = AviGlitch.open('/path/to/your.avi')
    avi.glitch(:keyframe) do |data|
      data.gsub(/\d/, '0')
    end
    avi.output('/path/to/broken.avi')
  2. Understand AviGlitch::RiffChunk

    master

    A RiffChunk represents a single parsed chunk within the RIFF structure.

    • Non-list chunks: Contain an id, binsize, and a value (the raw binary data).
    • List chunks: Contain an id, binsize, a list identifier, and a value which is an array of child RiffChunk objects.

    You can use #child(id) to get the first child matching an ID, or #children(id) to get all matching children.

  3. Initialize and parse an AVI file with AviGlitch::Avi

    master

    To work with an AVI file, create an instance of AviGlitch::Avi by passing the file path to the constructor. This automatically parses the RIFF structure and extracts frame indices.

    Note that the Avi object maintains the binary data in a temporary file to allow for efficient processing and modification without loading the entire file into memory.

    require 'aviglitch'
    
    # Initialize and parse the AVI file
    avi = AviGlitch::Avi.new('path/to/your/video.avi')
    
    # You can check if it was detected as an AVI2.0 file
    puts "Is AVI2? #{avi.is_avi2?}"
  4. Iterate over and modify AVI frames

    master

    The AviGlitch::Frames class (accessible via AviGlitch#frames) provides an Enumerable interface to access and manipulate individual frames in an AVI file. When iterating using each, you receive a reference to an AviGlitch::Frame object. Modifying the frame.data property within the block will apply those changes to the AVI file.

    Note that Frames behaves similarly to a Ruby Array, supporting common collection methods like push, slice, and concat.

    # Initialize the AVI file
    avi = AviGlitch.new '/path/to/your.avi'
    frames = avi.frames
    
    # Iterate and modify frame data
    frames.each do |frame|
      # Example: replace all digits in the frame data with '0'
      frame.data = frame.data.gsub(/\d/, '0')
    end
  5. Manipulate AVI frames manually

    master

    You can iterate through the frames of an AVI file using the frames method on the object returned by AviGlitch.open. Each frame object provides access to its raw data and metadata (such as whether it is a keyframe). After performing your manipulations, call output to save the glitched video to a new file.

    avi = AviGlitch.open '/path/to/your.avi'
    
    avi.frames.each do |frame|
      if frame.is_keyframe?
        # Manipulate the raw frame data
        frame.data = frame.data.gsub(/\d/, '0')
      end
    end
    
    avi.output '/path/to/broken.avi'
  6. Use the glitch method for frame manipulation

    master

    The glitch method provides a more concise way to apply transformations to specific types of frames. You can pass a symbol (such as :keyframe) to target specific frame types and provide a block that receives the frame's raw data. The return value of the block becomes the new frame data.

    avi = AviGlitch.open '/path/to/your.avi'
    
    # Apply a transformation to all keyframes
    avi.glitch(:keyframe) do |data|
      data.gsub(/\d/, '0')
    end
    
    avi.output '/path/to/broken.avi'
  7. Mutate keyframes into deltaframes

    master
    The mutate_keyframes_into_deltaframes!(range = nil) method allows you to change the flags of frames within a specified range. If a range is provided, it iterates through the frames in that range and sets frame.flag = 0 if the frame is currently a keyframe. If no range is provided, it applies to all frames.
  8. Modify 'movi' binary data with AviGlitch::Avi#process_movi

    master

    The process_movi method provides a way to perform bulk transformations on the video frame data. It yields the current @indices and the @movi binary data to a block.

    To apply changes, the block must return an array containing two elements: [new_indices, new_movi_data]. If the returned indices differ from the original, they will be replaced; if the returned binary data differs, the internal temporary file will be updated.

    avi.process_movi do |indices, movi|
      # Perform transformations on indices or movi data
      # ...
      
      # Return the updated versions
      [indices, movi]
    end
  9. Save glitched output with output() or write()

    master

    To save the manipulated AVI data to a file, use the output(path, do_file_close = true) method. You can also use the alias write(path).

    If do_file_close is set to true (the default), the underlying AVI file will be closed automatically after the output is written.

    # Save and close
    base.output("glitched_video.avi")
    
    # Save but keep the file open for further manipulation
    base.output("glitched_video.avi", false)
    
    # Using the alias
    base.write("glitched_video.avi")
  10. Use AviGlitch::Base to manipulate AVI frames

    master

    The AviGlitch::Base class is the primary interface for opening an AVI file, applying transformations (glitches) to individual frame data, and saving the result.

    To use it, you typically initialize it with a file path or an AviGlitch::Avi object, use the glitch method to modify frame data via a block, and then call output (or its alias write) to save the file.

    Note: The glitch method yields the frame data as a String. To apply a change, your block must return the modified data.

    # Example: Glitch all video frames by appending a character to the data
    base = AviGlitch::Base.new("input.avi")
    base.glitch(:videoframe) do |data|
      data + "glitch_marker"
    end
    base.output("output.avi")