added new UI for python version

Now python users can also enjoy the easy UI
This commit is contained in:
Akash Bora
2022-07-18 17:35:46 +05:30
committed by GitHub
parent 7933558b15
commit a964ecf891
37 changed files with 2546 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
#Author: Akash Bora
import os, shutil, subprocess, random, json
from pathlib import Path
import numpy as np
DIRPATH = Path(os.path.dirname(os.path.realpath(__file__)))
ffgac=str(DIRPATH.parent.parent).replace(os.sep, '/')+"/FFglitch/ffgac"
ffedit=str(DIRPATH.parent.parent).replace(os.sep, '/')+"/FFglitch/ffedit"
def library(input_video, output, mode, extract_from="", fluidity=0, size=0, s=0, e=0, vh=0, gop=1000):
def get_vectors(input_video):
subprocess.call(f'"{ffgac}" -i "{input_video}" -an -mpv_flags +nopimb+forcemv -qscale:v 0 -g "{gop}"' +
' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True)
subprocess.call(f'"{ffedit}" -i tmp.mpg -f mv:0 -e tmp.json', shell=True)
os.remove('tmp.mpg')
f = open('tmp.json', 'r')
raw_data = json.load(f)
f.close()
os.remove('tmp.json')
frames = raw_data['streams'][0]['frames']
vectors = []
for frame in frames:
try:
vectors.append(frame['mv']['forward'])
except:
vectors.append([])
return vectors
def apply_vectors(vectors, input_video, output_video, method='add'):
subprocess.call(f'"{ffgac}" -i "{input_video}" -an -mpv_flags +nopimb+forcemv -qscale:v 0 -g "{gop}"' +
' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True)
to_add = '+' if method == 'add' else ''
script_path = 'apply_vectors.js'
script_contents = '''
var vectors = [];
var n_frames = 0;
function glitch_frame(frame) {
let fwd_mvs = frame["mv"]["forward"];
if (!fwd_mvs || !vectors[n_frames]) {
n_frames++;
return;
}
for ( let i = 0; i < fwd_mvs.length; i++ ) {
let row = fwd_mvs[i];
for ( let j = 0; j < row.length; j++ ) {
let mv = row[j];
try {
mv[0] ''' + to_add + '''= vectors[n_frames][i][j][0];
mv[1] ''' + to_add + '''= vectors[n_frames][i][j][1];
} catch {}
}
}
n_frames++;
}
'''
with open(script_path, 'w') as f:
f.write(script_contents.replace('var vectors = [];', f'var vectors = {json.dumps(vectors)};'))
subprocess.call(f'"{ffedit}" -i tmp.mpg -f mv -s "{script_path}" -o "{output_video}"', shell=True)
os.remove('apply_vectors.js')
os.remove('tmp.mpg')
def shuffle(output):
if os.path.isdir("cache"):
shutil.rmtree("cache")
os.mkdir("cache")
base=os.path.basename(input_video)
fin="cache/"+base[:-4]+".mpg"
subprocess.call(f'"{ffgac}" -i "{input_video}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -g "{gop}" -y "{fin}"')
os.mkdir("cache/raws")
framelist=[]
subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache/raws/frames_%04d.raw')
frames=os.listdir("cache/raws")
siz=size
framelist.extend(frames)
chunked_list=[]
chunk_size=siz
for i in range(0, len(framelist), chunk_size):
chunked_list.append(framelist[i:i+chunk_size])
random.shuffle(chunked_list)
framelist.clear()
for k in frames[0:siz]:
framelist.append(k)
for i in chunked_list:
for j in i:
if not j in framelist:
framelist.append(j)
out_data = b''
for fn in framelist:
with open("cache/raws/"+fn, 'rb') as fp:
out_data += fp.read()
with open(output, 'wb+') as fp:
fp.write(out_data)
fp.close()
shutil.rmtree("cache")
def rise(output):
if os.path.isdir("cache"):
shutil.rmtree("cache")
os.mkdir("cache")
base=os.path.basename(input_video)
fin="cache/"+base[:-4]+".mpg"
qua=''
subprocess.call(f'"{ffgac}" -i "{input_video}" -an -vcodec mpeg2video -f rawvideo -mpv_flags +nopimb -qscale:v 6 -r 30 -g "{gop}" -y "{fin}"')
os.mkdir("cache/raws")
framelist=[]
subprocess.call(f'"{ffgac}" -i "{fin}" -vcodec copy cache/raws/frames_%04d.raw')
kil=e
po=s
if po==0:
po=1
frames=os.listdir("cache/raws")
for i in frames[po:(po+kil)]:
os.remove("cache/raws/"+i)
frames.clear()
frames=os.listdir("cache/raws")
framelist.extend(frames)
out_data = b''
for fn in framelist:
with open("cache/raws/"+fn, 'rb') as fp:
out_data += fp.read()
with open(output, 'wb') as fp:
fp.write(out_data)
fp.close()
shutil.rmtree("cache")
def average(frames):
if not frames:
return []
return np.mean(np.array([x for x in frames if x != []]), axis=0).tolist()
def fluid(frames):
average_length = fluidity
if average_length==1:
average_length=2
return [average(frames[i + 1 - average_length: i + 1]) for i in range(len(frames))]
def movement(frames):
for frame in frames:
if not frame:
continue
for row in frame:
for col in row:
col[vh] = 0
return frames
if(mode==1):
transfer_to=input_video
vectors = []
if extract_from:
vectors = get_vectors(extract_from)
if transfer_to == '':
with open(output, 'w') as f:
json.dump(vectors, f)
apply_vectors(vectors, transfer_to, output)
elif(mode==2):
apply_vectors(movement(get_vectors(input_video)), input_video, output, method='')
elif(mode==3):
apply_vectors(fluid(get_vectors(input_video)), input_video, output, method='')
elif(mode==4):
shuffle(output)
elif(mode==5):
rise(output)

View File

@@ -0,0 +1,15 @@
#Author: Akash Bora
import os, subprocess
from pathlib import Path
DIRPATH = Path(os.path.dirname(os.path.realpath(__file__)))
ffgac=str(DIRPATH.parent.parent).replace(os.sep, '/')+"/FFglitch/ffgac"
ffedit=str(DIRPATH.parent.parent).replace(os.sep, '/')+"/FFglitch/ffedit"
def mosh(input_video, output_video, mode, effect='', scriptfile='', gop=1000):
if mode==1:
script_path=scriptfile
elif mode==2:
script_path=str(DIRPATH).replace(os.sep, '/')+"/jscripts/"+effect+".js"
subprocess.call(f'"{ffgac}" -i "{input_video}" -an -mpv_flags +nopimb+forcemv -qscale:v 0 -b:v 20M -minrate 20M -maxrate 20M -bufsize 2M -g "{gop}"' +
' -vcodec mpeg2video -f rawvideo -y tmp.mpg', shell=True)
subprocess.call(f'"{ffedit}" -i tmp.mpg -f mv -s "{script_path}" -o "{output_video}"', shell=True)
os.remove('tmp.mpg')

View File

@@ -0,0 +1,75 @@
// dd_ring_buffer.js
// works kinda like an audio delay
// stacks the previous n frames into a buffer
// global variable holding forward motion vectors from previous frames
var prev_fwd_mvs = [ ];
// change these values to use a smaller or greater number of frames to
// perform the average of motion vectors
// try making the delay long enough to overlap an edit in the content ...
var delay = 10;
// divisor controls "feedback" ... or "feedforward" which ever is a better description ...
var feedback = 0.5; // a number between 0.000001 and .... yeah - controls how much of the buffered mv gets into the next pass
var divisor = 1.0/feedback;
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
// update variable holding forward motion vectors from previous
// frames. note that we perform a deep copy of the clean motion
// vector values before modifying them.
let json_str = JSON.stringify(fwd_mvs);
let deep_copy = JSON.parse(json_str);
// push to the end of array
prev_fwd_mvs.push(deep_copy);
// drop values from earliest frames to always keep the same tail
// length
if ( prev_fwd_mvs.length > delay )
prev_fwd_mvs = prev_fwd_mvs.slice(1);
// bail out if we still don't have enough frames
if ( prev_fwd_mvs.length != delay )
return;
// replace all motion vectors of current frame with an average
// of the motion vectors from the previous 10 frames
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
let delay_row = prev_fwd_mvs[0][i];
let insert_row = prev_fwd_mvs[delay-1][i];
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
let dmv = delay_row[j];
let imv = insert_row[j];
// THIS IS WHERE THE MAGIC HAPPENS
// temp copy of the incoming vectors
let x = mv[0];
let y = mv[1];
// pull their replacements out of the buffer
mv[0] = dmv[0];
mv[1] = dmv[1];
// feedback the 'old' with the 'new' for next time
imv[0] = (dmv[0] / divisor) + x;
imv[1] = (dmv[1] / divisor) + y;
// rinse and repeat
}
}
}

View File

@@ -0,0 +1,71 @@
// dd_delay.js
// works kinda like an audio delay
// stacks the previous n frames into a buffer
// global variable holding forward motion vectors from previous frames
var prev_fwd_mvs = [ ];
// change these values to use a smaller or greater number of frames to
// perform the average of motion vectors
// try making the delay long enough to overlap an edit in the content ...
var delay = 20;
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
// update variable holding forward motion vectors from previous
// frames. note that we perform a deep copy of the clean motion
// vector values before modifying them.
let json_str = JSON.stringify(fwd_mvs);
let deep_copy = JSON.parse(json_str);
// push to the end of array
prev_fwd_mvs.push(deep_copy);
// drop values from earliest frames to always keep the same tail
// length
if ( prev_fwd_mvs.length > delay )
prev_fwd_mvs = prev_fwd_mvs.slice(1);
// bail out if we still don't have enough frames
if ( prev_fwd_mvs.length != delay )
return;
// replace all motion vectors of current frame with an average
// of the motion vectors from the previous 10 frames
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
let delay_row = prev_fwd_mvs[0][i];
let insert_row = prev_fwd_mvs[delay-1][i];
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
let dmv = delay_row[j];
let imv = insert_row[j];
// THIS IS WHERE THE MAGIC HAPPENS
// temp copy of the incoming vectors
let x = mv[0];
let y = mv[1];
// pull their replacements out of the buffer
mv[0] = dmv[0];
mv[1] = dmv[1];
// feedback the 'old' with the 'new' for next time
imv[0] = x;
imv[1] = y;
// rinse and repeat
}
}
}

View File

@@ -0,0 +1,58 @@
// dd_RandomDamage(invertRandomN).js
// invert x and y component of mv for random number of frames if threshold met for frame
let threshold = 95;
var TRIGGERED = 0;
var nFrames = 10;
var frameCount = 0;
var MAGNITUDE = 20;
function glitch_frame(frame)
{
var do_or_not = Math.random() * 100;
if(do_or_not > threshold){
if(TRIGGERED > 0){
}else{
TRIGGERED = 1;
frameCount = 0;
nFrames = Math.random() * MAGNITUDE;
}
}
// only do the glitch if our random number crosses the threshold
if(TRIGGERED > 0 & frameCount <= nFrames){
frameCount++;
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
var M_H = fwd_mvs.length/2;
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
var M_W = row.length/2;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
// STOP XY
mv[0] = 0 - mv[0];
mv[1] = 0 - mv[1];
}
}
}else{
TRIGGERED = 0;
}
}

View File

@@ -0,0 +1,52 @@
// dd_mirror_X.js
// clean buffer :
var buffer = [ ];
var ZOOM = -20;
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
// note that we perform a deep copy of the clean motion
// vector values before modifying them.
let json_str = JSON.stringify(fwd_mvs);
let deep_copy = JSON.parse(json_str);
// stick em in the buffer
buffer = deep_copy;
var M_H = fwd_mvs.length/2;
// VERTICALLY
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
var row2 = buffer[i];
//var row2 = fwd_mvs[(fwd_mvs.length-1)-i];
var M_W = row.length/2;
// HORIZONTALLY
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
var mv2 = row2[(row.length - 1) - j];
// THIS IS WHERE THE MAGIC HAPPENS
//if(i>M_W){
mv[0] = 0-mv2[0];
mv[1] = mv2[1];
//}
}
}
}

View File

@@ -0,0 +1,67 @@
// dd_MultiplySlowest_50.js
// Multiply slowest moving mv's
var LARGEST = 0;
var SOME_PERCENTAGE = 0.5;
var MULTIPLE = 10;
// global variable holding forward motion vectors from previous frames
var prev_fwd_mvs = [ ];
// change this value to use a smaller or greater number of frmes to average
var tail_length = 20;
function glitch_frame(frame)
{
LARGEST = 0;
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
// 1st loop - find the fastest mv
// this ends-up in LARGEST as the square of the hypotenuse (mv[0]*mv[0]) + (mv[1]*mv[1])
let W = fwd_mvs.length;
for ( let i = 0; i < fwd_mvs.length; i++ )
{
let row = fwd_mvs[i];
// rows
let H = row.length;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MEASUREMENT HAPPENS
var this_mv = (mv[0] * mv[0])+(mv[1] * mv[1]);
if ( this_mv > LARGEST){
LARGEST = this_mv;
}
}
}
// then find those mv's which are bigger than SOME_PERCENTAGE of LARGEST
// and then replace them with the average mv from the last n frames
for ( let i = 0; i < fwd_mvs.length; i++ )
{
let row = fwd_mvs[i];
// rows
let H = row.length;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
var this_mv = (mv[0] * mv[0])+(mv[1] * mv[1]);
if (this_mv < (LARGEST * SOME_PERCENTAGE)){
mv[0] = mv[0] * MULTIPLE;
mv[1] = mv[1] * MULTIPLE;
}
}
}
}

View File

@@ -0,0 +1,37 @@
// dd_sheer.js
var ZOOM = -20;
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
var M_H = fwd_mvs.length/2;
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
var M_W = row.length/2;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
//if(i>M_W){
mv[0] = mv[0] + ((i - M_W) / 100)*ZOOM;
mv[1] = mv[1] + ((j - M_H) / 100)*ZOOM;
//}
}
}
}

View File

@@ -0,0 +1,74 @@
// dd_RandomDamage(antiGrav).js
// anitgravityify if threshold met for frame
let threshold = 98;
// global variable holding forward motion vectors from previous frames
var old_mvs = [ ];
// a variable for gravity
var rt = 0;
var gravity = 0
var orig_gravity = 5;
var TRIGGERED = 0;
var frameCount = 10;
var count = 0;
function glitch_frame(frame)
{
var do_or_not = Math.random() * 100;
// only do the glitch if our random number crosses the threshold
if(do_or_not > threshold | TRIGGERED == 1){
if(TRIGGERED == 0){
gravity = orig_gravity;
TRIGGERED = 1;
rt = 0;
}
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
// buffer first set of vectors. . .
if(rt == 0){
let json_str = JSON.stringify(fwd_mvs);
let deep_copy = JSON.parse(json_str);
// push to the end of array
old_mvs[0] = (deep_copy);
rt = 1;
}
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
let old_row = old_mvs[0][i];
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
let omv = old_row[j];
// THIS IS WHERE THE MAGIC HAPPENS
mv[0] = mv[0];
//if(mv[1] < 0){
var nmv = mv[1];
mv[1] = omv[1];
omv[1] = nmv + omv[1] + gravity;
//gravity++;
//}else{
// mv[1] = mv[1];
//}
}
}
count++;
if(count >= frameCount){
TRIGGERED = 0;
count = 0;
}
}
}

View File

@@ -0,0 +1,38 @@
// dd_zero.js
// only fuck things up if mv > movement_threshold
var movement_threshold = 3;
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
// columns
let W = fwd_mvs.length;
for ( let i = 0; i < fwd_mvs.length; i++ )
{
let row = fwd_mvs[i];
// rows
let H = row.length;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
if ( (mv[0] * mv[0])+(mv[1] * mv[1]) > movement_threshold*movement_threshold){
//mv[0] = Math.sin(i/W*Math.PI*2)*mv[0];
//mv[1] = Math.cos(j/H*Math.PI*2)*mv[1];
mv[0] = 0;//mv[0] * 10;
mv[1] = 0;//mv[1] * 10;
}
}
}
}

View File

@@ -0,0 +1,37 @@
// dd_slam_zoom_in.js
var ZOOM = 20;
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
var M_H = fwd_mvs.length/2;
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
var M_W = row.length/2;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
//if(i>M_W){
mv[0] = ((M_W - j) / 100)*ZOOM;
mv[1] = ((M_H - i) / 100)*ZOOM;
//}
}
}
}

View File

@@ -0,0 +1,68 @@
// dd_RandomDamage(progZoom).js
// progressive Zoom x and y components of mv if threshold met for frame
let threshold = 95;
var ZOOM = 0;
var doZOOM = 0;
var TRIGGERED = 0;
var nFrames = 5;
var frameCount = 0;
function glitch_frame(frame)
{
var do_or_not = Math.random() * 100;
if(do_or_not > threshold){
if(TRIGGERED > 0){
}else{
TRIGGERED = 1;
frameCount = 0;
ZOOM = 0;
}
}
// only do the glitch if our random number crosses the threshold
if(TRIGGERED > 0 & frameCount <= nFrames){
frameCount++;
ZOOM+= 10
var do_dir = Math.random() * 100;
if(do_dir > 50){
doZOOM = 0 - ZOOM;
}else{
doZOOM = ZOOM
}
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
var M_H = fwd_mvs.length/2;
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
var M_W = row.length/2;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
// ZOOM X & Y VECTORS
mv[0] = mv[0] + ((M_W - j) / 10)*doZOOM;
mv[1] = mv[1] + ((M_H - i) / 10)*doZOOM;
}
}
}else{
TRIGGERED = 0;
}
}

View File

@@ -0,0 +1,56 @@
// dd_RandomDamage(stopXY).js
// stop x and y component of mv for n framesif threshold met for frame
let threshold = 95;
var TRIGGERED = 0;
var nFrames = 10;
var frameCount = 0;
function glitch_frame(frame)
{
var do_or_not = Math.random() * 100;
if(do_or_not > threshold){
if(TRIGGERED > 0){
}else{
TRIGGERED = 1;
frameCount = 0;
}
}
// only do the glitch if our random number crosses the threshold
if(TRIGGERED > 0 & frameCount <= nFrames){
frameCount++;
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
var M_H = fwd_mvs.length/2;
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
var M_W = row.length/2;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
// STOP XY
mv[0] = 0;
mv[1] = 0;
}
}
}else{
TRIGGERED = 0;
}
}

View File

@@ -0,0 +1,29 @@
var randomness = 10;
var bias = (randomness/2);
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
mv[0] = mv[0] + (Math.floor((Math.random() * randomness) -bias));
mv[1] = mv[1] + (Math.floor((Math.random() * randomness) -bias));
}
}
}

View File

@@ -0,0 +1,38 @@
// dd_zoom_in.js
var ZOOM = 20;
function glitch_frame(frame)
{
// bail out if we have no motion vectors
let mvs = frame["mv"];
if ( !mvs )
return;
// bail out if we have no forward motion vectors
let fwd_mvs = mvs["forward"];
if ( !fwd_mvs )
return;
var M_H = fwd_mvs.length/2;
// clear horizontal element of all motion vectors
for ( let i = 0; i < fwd_mvs.length; i++ )
{
// loop through all rows
let row = fwd_mvs[i];
var M_W = row.length/2;
for ( let j = 0; j < row.length; j++ )
{
// loop through all macroblocks
let mv = row[j];
// THIS IS WHERE THE MAGIC HAPPENS
//if(i>M_W){
mv[0] = mv[0] + ((M_W - j) / 100)*ZOOM;
mv[1] = mv[1] + ((M_H - i) / 100)*ZOOM;
//}
}
}
}

View File

@@ -0,0 +1,35 @@
#Author: Akash Bora
import subprocess
def Datamosh(filename, outf, s, e, p, fps=30):
END_FRAME_HEX = b'00dc'
I_FRAME_HEX = b'\x00\x01\xb0'
def main(filename, effect_sec_list, p_frames_mult):
mosh(effect_sec_list, p_frames_mult)
def mosh(effect_sec_list, p_frames_mult):
with open(filename, 'rb') as in_file, open(outf, 'wb') as out_file:
frames = split_file(in_file, END_FRAME_HEX)
for index, frame in enumerate(frames):
if not is_need_effect_here(index / fps, effect_sec_list):
out_file.write(frame + END_FRAME_HEX)
continue
if not is_iframe(frame):
out_file.write((frame + END_FRAME_HEX) * p_frames_mult)
def split_file(fp, marker, blocksize=4096):
buffer = b''
for block in iter(lambda: fp.read(blocksize), b''):
buffer += block
while True:
markerpos = buffer.find(marker)
if markerpos == -1:
break
yield buffer[:markerpos]
buffer = buffer[markerpos + len(marker):]
yield buffer
def is_need_effect_here(curr_sec, effect_sec_list):
return any(start < curr_sec < end for start, end in effect_sec_list)
def is_iframe(frame):
return frame[5:8] == I_FRAME_HEX
start=s
end=e
pf=p
main(filename,[(start,end)],pf)

View File

@@ -0,0 +1,64 @@
#Author: Akash Bora
from pymosh import Index
from pymosh.codec.mpeg4 import is_iframe
from itertools import islice
class library():
def glide(interval, filename, outfile):
f = Index.from_file(filename)
buf = [None]
def process_frame(frame):
if buf[0] == None or not is_iframe(frame):
buf[0] = frame
else:
frame = buf[0]
return frame
for stream in f.video:
newstream = []
newstream.append(stream[0])
ix = 0
jx = 0
for i in stream[1:]:
ix += 1
jx += 1
if ix < interval:
newstream.append(process_frame(stream[jx]))
else:
newstream.append(newstream[-1])
if ix > interval * 2:
ix = 0
stream.replace(newstream)
f.rebuild()
with open(outfile, 'wb') as out:
f.write(out)
def avi_sort(filename, outfile, mode, rev):
f = Index.from_file(filename)
for stream in f.video:
if mode==0:
sorted_stream = sorted(stream, key=len, reverse=rev)
else:
sorted_stream = sorted(stream, key=lambda s: s[len(s)-6], reverse=rev)
stream.replace(sorted_stream)
f.rebuild()
with open(outfile, 'wb') as out:
f.write(out)
def process_streams(in_filename, out_filename, mid=''):
def echo(stream, midpoint):
all_frames = list(stream)
pframes = [f for f in all_frames if not is_iframe(f)]
midpoint_idx = int(len(all_frames)*midpoint)
frames = all_frames[:midpoint_idx]
while len(frames) < len(all_frames):
frames += pframes[:(len(all_frames) - len(frames))]
return frames
mode=echo
f = Index.from_file(in_filename)
for stream in f.video:
midpoint=mid
drifted = list(mode(stream, midpoint))
stream.replace(drifted)
f.rebuild()
with open(out_filename, 'wb') as out:
f.write(out)

View File

@@ -0,0 +1,43 @@
#Author: Akash Bora
def Datamosh(filename,outfile,s,e,p,fps):
def write_frame(frame):
out_file.write(frame_start + frame)
def mosh_delta_repeat(n_repeat):
if n_repeat=="1":
n_repeat=2
repeat_frames = []
repeat_index = 0
for index, frame in enumerate(frames):
if (frame[5:8] != iframe and frame[5:8] != pframe) or not start_frame <= index < end_frame:
write_frame(frame)
continue
if len(repeat_frames) < n_repeat and frame[5:8] != iframe:
repeat_frames.append(frame)
write_frame(frame)
elif len(repeat_frames) == n_repeat:
write_frame(repeat_frames[repeat_index])
repeat_index = (repeat_index + 1) % n_repeat
else:
write_frame(frame)
start_frame = s
end_frame = e
if end_frame==1:
end_frame=1000
input_avi = filename
delta = p
in_file = open(input_avi, 'rb')
output_avi= outfile
in_file_bytes = in_file.read()
out_file = open(output_avi, 'wb')
frame_start = bytes.fromhex('30306463')
frames = in_file_bytes.split(frame_start)
out_file.write(frames[0])
frames = frames[1:]
iframe = bytes.fromhex('0001B0')
pframe = bytes.fromhex('0001B6')
n_video_frames = len([frame for frame in frames if frame[5:8] == iframe or frame[5:8] == pframe])
if end_frame < 0:
end_frame = n_video_frames
mosh_delta_repeat(delta)
in_file.close()
out_file.close()

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Kaspar RAVEL
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,234 @@
#Original Author: Kasper Ravel
#Modified by: Akash Bora
import os, re, random, struct
from itertools import chain
from itertools import repeat
def mosh(infile, outfile, m, c, n, a, f, k):
print (" _ _ ")
print ("| | | | ")
print ("| |_ ___ _ __ ___ __ _| |_ ___ ")
print ("| __/ _ \| '_ ` _ \ / _` | __/ _ \ ")
print ("| || (_) | | | | | | (_| | || (_) |")
print (" \__\___/|_| |_| |_|\__,_|\__\___/ ")
print ("Tomato Automosh v2.0")
print ("\\\\ Audio Video Interleave breaker")
print (" ")
print ("glitch tool made with love for the glitch art community <3")
print ("___________________________________")
filein = infile
mode = m
countframes = c
positframes = n
audio = a
firstframe = f
kill = k
if filein is None or os.path.exists(filein) == False:
print("> step 0/5: valid input file required!")
print("use -h to see help")
exit()
#define temp directory and files
temp_nb = random.randint(10000, 99999)
temp_dir = "temp-" + str(temp_nb)
temp_hdrl = temp_dir +"\\hdrl.bin"
temp_movi = temp_dir +"\\movi.bin"
temp_idx1 = temp_dir +"\\idx1.bin"
os.mkdir(temp_dir)
#Define constrain function for jiggle :3
def constrain(val, min_val, max_val):
return min(max_val, max(min_val, val))
######################################
### STREAM FILE INTO WORK DIR BINS ###
######################################
print("> step 1/5 : streaming into binary files")
def bstream_until_marker(bfilein, bfileout, marker=0, startpos=0):
chunk = 1024
filesize = os.path.getsize(bfilein)
if marker :
marker = str.encode(marker)
with open(bfilein,'rb') as rd:
with open(bfileout,'ab') as wr:
for pos in range(startpos, filesize, chunk):
rd.seek(pos)
buffer = rd.read(chunk)
if marker:
if buffer.find(marker) > 0 :
marker_pos = re.search(marker, buffer).start() # position is relative to buffer glitchedframes
marker_pos = marker_pos + pos # position should be absolute now
split = buffer.split(marker, 1)
wr.write(split[0])
return marker_pos
else:
wr.write(buffer)
else:
wr.write(buffer)
#make 3 files, 1 for each chunk
movi_marker_pos = bstream_until_marker(filein, temp_hdrl, "movi")
idx1_marker_pos = bstream_until_marker(filein, temp_movi, "idx1", movi_marker_pos)
bstream_until_marker(filein, temp_idx1, 0, idx1_marker_pos)
####################################
### FUN STUFF WITH VIDEO CONTENT ###
####################################
print("> step 2/5 : constructing frame index")
with open(temp_movi,'rb') as rd:
chunk = 1024
filesize = os.path.getsize(temp_movi)
frame_table = []
for pos in range(0, filesize, chunk):
rd.seek(pos)
buffer = rd.read(chunk)
#build first list with all adresses
for m in (re.finditer(b'\x30\x31\x77\x62', buffer)): # find iframes
if audio : frame_table.append([m.start() + pos, 'sound'])
for m in (re.finditer(b'\x30\x30\x64\x63', buffer)): # find b frames
frame_table.append([m.start() + pos, 'video'])
#then remember to sort the list
frame_table.sort(key=lambda tup: tup[0])
l = []
l.append([0,0, 'void'])
max_frame_size = 0
#build tuples for each frame index with frame sizes
for n in range(len(frame_table)):
if n + 1 < len(frame_table):
frame_size = frame_table[n + 1][0] - frame_table[n][0]
else:
frame_size = filesize - frame_table[n][0]
max_frame_size = max(max_frame_size, frame_size)
l.append([frame_table[n][0],frame_size, frame_table[n][1]])
########################
### TIME FOR SOME FX ###
########################
# variables that make shit work
clean = []
final = []
# keep first video frame or not
if firstframe:
for x in l:
if x[2] == 'video':
clean.append(x)
break
# clean the list by killing "big" frames
for x in l:
if x[1] <= (max_frame_size * kill) :
clean.append(x)
# FX modes
if mode == "void":
print('> step 3/5 : mode void')
final = clean
if mode == "random":
print('> step 3/5 : mode random')
final = random.sample(clean,len(clean))
if mode == "reverse":
print('> step 3/5 : mode reverse')
final = sum(zip(clean[::-1], clean[:-1]), ())
if mode == "invert":
print('> step 3/5 : mode invert')
final = sum(zip(clean[1::2], clean[::2]), ())
if mode == 'bloom':
print('> step 3/5 : mode bloom')
repeat = int(countframes)
frame = int(positframes)
## split list
lista = clean[:frame]
listb = clean[frame:]
## rejoin list with bloom
final = lista + ([clean[frame]]*repeat) + listb
if mode == 'pulse':
print('> step 3/5 : mode pulse')
pulselen = int(countframes)
pulseryt = int(positframes)
j = 0
for x in clean:
i = 0
if(j % pulselen == 0):
while i < pulselen :
final.append(x)
i = i + 1
else:
final.append(x)
j = j + 1
if mode == "jiggle":
print('> step 3/5 : mode jiggle')
#print('*needs debugging lol help thx*') # didn't pandy's branch fix this?
amount = int(positframes)
final = [clean[constrain(x+int(random.gauss(0,amount)),0,len(clean)-1)] for x in range(0,len(clean))]
if mode == "overlap":
print('> step 3/5 : mode overlap')
pulselen = int(countframes)
pulseryt = int(positframes)
clean = [clean[i:i+pulselen] for i in range(0,len(clean),pulseryt)]
final = [item for sublist in clean for item in sublist]
if mode == 'exponential':#Ask Kasper to add these modes (Note by Akash)
print('> step 3/5 : mode exponential')
print('sorry, currently not implemented. using void..')
if mode == 'swap':
print('> step 3/5 : mode swap')
print('sorry, currently not implemented. using void..')
####################################
### PUT VIDEO FILE BACK TOGETHER ###
####################################
print("> step 4/5 : putting things back together")
#name new file
fileout = outfile
#delete old file
if os.path.exists(fileout):
os.remove(fileout)
bstream_until_marker(temp_hdrl, fileout)
with open(temp_movi,'rb') as rd:
filesize = os.path.getsize(temp_movi)
with open(fileout,'ab') as wr:
wr.write(struct.pack('<4s', b'movi'))
for x in final:
if x[0] != 0 and x[1] != 0:
rd.seek(x[0])
wr.write(rd.read(x[1]))
bstream_until_marker(temp_idx1, fileout)
#remove unnecessary temporary files and folders
os.remove(temp_hdrl)
os.remove(temp_movi)
os.remove(temp_idx1)
os.rmdir(temp_dir)
print("> step 5/5 : done - final idx size : " + str(len(final)))