videofucker 1.0.0

dotnet add package videofucker --version 1.0.0                
NuGet\Install-Package videofucker -Version 1.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="videofucker" Version="1.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add videofucker --version 1.0.0                
#r "nuget: videofucker, 1.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install videofucker as a Cake Addin
#addin nuget:?package=videofucker&version=1.0.0

// Install videofucker as a Cake Tool
#tool nuget:?package=videofucker&version=1.0.0                

VideoF*cker 3000

VideoF*cker is an FFmpeg.NET-based library for corrupting video in a manner similar to ATSC 1.0 terrestrial television. It was initially written for a CLI, but after deciding that the CLI wasn't powerful enough, it has been released as a library. I feel that this makes it much more useful for the video artist community at large.

Why's it called that?

It sounded funny at the time. It's also fairly descriptive!

How does it work?

Like so.

using VideoFucker.Converters;
using VideoFucker.Moshers;

// bring-your-own example.mp4!
string videoPath = "./example.mp4";

// convert video to MPEG-2 -- asynchronously!
AtscConverter atsc = new AtscConverter();
string atscVideoPath = await atsc.Convert(videoPath);

// corrupt video with Talons (most chaotic mosher)
TalonsMosher mosh = new TalonsMosher();
string corruptedVideoPath = mosh.Mosh(atscVideoPath);

// and convert back to x264 -- which attempts to repair the video
x264Converter repair = new x264Converter();
string outputVideoPath = await repair.Convert(corruptedVideoPath);

// clean up
File.Delete(atscVideoPath);
File.Delete(corruptedVideoPath);

There's a couple of helper classes called MoshHost and ConvHost in VideoFucker.Hosts to ease the production of external interfaces for VideoFucker. You can use them like so:

using VideoFucker.Converters;
using VideoFucker.Moshers;
using VideoFucker.Hosts;

string videoPath = "./example.mp4";
Type converter = typeof(AtscConverter);
Type mosher = typeof(AtscMosher);
Type repairer = typeof(x264Converter);

// convert
string convertedPath = await ConvHost.Convert(converter, videoPath);
// mosh
string moshedPath = MoshHost.Mosh(mosher, convertedPath);
// repair
string outputPath = await ConvHost.Convert(repairer, moshedPath);

// clean up
File.Delete(convertedPath);
File.Delete(moshedPath);

Defining Your Own Converter

If all you want to do is place video in a new container, you can simply subclass Converter and then redefine its constructor. For example, here is the AtscConverter's full class definition:

public class AtscConverter : Converter {
    public AtscConverter() {
        Name = "ATSC 1.0 / MPEG2-TS";
        Extension = "ts";
        Codec = VideoCodec.mpeg2video;
        Container = VideoFormat.mpegts;
    }
}

If you want to do more than this, you can simply override the Convert method.

Defining Your Own Mosher

Defining moshers works similarly. For example, FuzzyMosher, which randomly fuzzes integer values:

public class FuzzyMosher : Mosher {
    public int odds, range;
    public FuzzyMosher() {
        Name = "Fuzzer";
        odds = 50;
        range = 25;
    }
    protected override int MoshValue(int source) {
        if (Random.Shared.Next(0, odds) == odds / 2)
            // randomly nudge byte by +/- a random value in-range
            return source + Random.Shared.Next(-range, range);
        else return source;
    }
}

MoshValue operates on every affected byte. If you'd like to define your own logic for determining which bytes are affected, you can override Mosh instead.

Quick Reference and Effects

AtscConverter is useful for creating resilient MPEG2-TS video streams that still corrupt in interesting ways. x264Converter attempts to restore damaged video to make it playable in most video players (tested in VLC and Discord).

In terms of effects, there are, in order from most to least realistic:

  • GoodAtscMosher - simulates a light reduction in signal strength for an ATSC 1.0 stream
  • AtscMosher - simulates a decent reduction in signal strength for an ATSC 1.0 stream
  • BadAtscMosher - simulates a heavy reduction in signal strength for an ATSC 1.0 stream
  • SignalMosher - simulates a random reduction in byte value
  • DropoutMosher - simulates a loss of signal at random intervals
  • FuzzyMosher - randomly adjusts integer values
  • InversionMosher - randomly subtracts integer values from 0xFF
  • TalonsMosher - randomly repeats bytes (drags them out), produces tremendous artifacting!
  • UpcaseMosher - upcases every value which matches a lowercase UTF-8 letter
  • DowncaseMosher - produces unplayable video. Not very helpful!

Known Issues

  • Sometimes video will be too degraded for FFmpeg to restore, in which case it will simply return a path to a broken video. I'm not too sure how to solve this one.
  • DowncaseMosher always produces unplayable videos. Pretty sure this is because the MPEG-TS sync byte is 'G', which means it will become 'g' and thus impossible to locate.
  • If your FFmpeg binary isn't called ffmpeg or ffmpeg.exe and isn't in $PATH, it will not be detected. Setting the environment variable FFMPEG_PATH solves this.
  • If video is extremely degraded, x264Converter will sometimes hang while FFmpeg tries anyways. This can take a very long time and may not produce useful results.
  • Likewise, if a video is too degraded to be restored, FFmpeg will simply return an unplayable video.
  • When using MoshHost or ConvHost, you cannot set parameters (which take the form of class values) on Moshers or Converters.

Unknown Issues

Should you run into a problem that isn't addressed above, please create a Git issue at Codeberg. If you don't feel up to making a Codeberg account, you can contact the project maintainer (Jenny) at tobskep@aol.com.

Acknowledgements

Thank you to reina for technical help with MPEG2-TS streams, and thank you to at0m for video corruption assistance. Without their help, this project would not function as well* as it does.

This project would also not be usable (or even possible) without the excellent FFmpeg.NET project, and all those responsible for the .NET Core runtime and the .NET standard library. Thank you!

License

This project is made available under the MIT license. For complete terms, see LICENSE. If this doesn't suit your usecase, you're better off writing your own.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 77 8/7/2024