mirror of
https://github.com/Akascape/Datamosher-Pro.git
synced 2025-12-16 21:29:57 +01:00
added new UI for python version
Now python users can also enjoy the easy UI
This commit is contained in:
154
Python Version/DatamoshLib/FFG_effects/basic_modes.py
Normal file
154
Python Version/DatamoshLib/FFG_effects/basic_modes.py
Normal 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)
|
||||
15
Python Version/DatamoshLib/FFG_effects/external_script.py
Normal file
15
Python Version/DatamoshLib/FFG_effects/external_script.py
Normal 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')
|
||||
75
Python Version/DatamoshLib/FFG_effects/jscripts/Buffer.js
Normal file
75
Python Version/DatamoshLib/FFG_effects/jscripts/Buffer.js
Normal 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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
71
Python Version/DatamoshLib/FFG_effects/jscripts/Delay.js
Normal file
71
Python Version/DatamoshLib/FFG_effects/jscripts/Delay.js
Normal 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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
52
Python Version/DatamoshLib/FFG_effects/jscripts/Mirror.js
Normal file
52
Python Version/DatamoshLib/FFG_effects/jscripts/Mirror.js
Normal 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];
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Python Version/DatamoshLib/FFG_effects/jscripts/Noise.js
Normal file
67
Python Version/DatamoshLib/FFG_effects/jscripts/Noise.js
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Python Version/DatamoshLib/FFG_effects/jscripts/Shear.js
Normal file
37
Python Version/DatamoshLib/FFG_effects/jscripts/Shear.js
Normal 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;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Python Version/DatamoshLib/FFG_effects/jscripts/Shift.js
Normal file
74
Python Version/DatamoshLib/FFG_effects/jscripts/Shift.js
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Python Version/DatamoshLib/FFG_effects/jscripts/Sink.js
Normal file
38
Python Version/DatamoshLib/FFG_effects/jscripts/Sink.js
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Python Version/DatamoshLib/FFG_effects/jscripts/Slam Zoom.js
Normal file
37
Python Version/DatamoshLib/FFG_effects/jscripts/Slam Zoom.js
Normal 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;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
Python Version/DatamoshLib/FFG_effects/jscripts/Slice.js
Normal file
68
Python Version/DatamoshLib/FFG_effects/jscripts/Slice.js
Normal 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;
|
||||
}
|
||||
}
|
||||
56
Python Version/DatamoshLib/FFG_effects/jscripts/Stop.js
Normal file
56
Python Version/DatamoshLib/FFG_effects/jscripts/Stop.js
Normal 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;
|
||||
}
|
||||
}
|
||||
29
Python Version/DatamoshLib/FFG_effects/jscripts/Vibrate.js
Normal file
29
Python Version/DatamoshLib/FFG_effects/jscripts/Vibrate.js
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Python Version/DatamoshLib/FFG_effects/jscripts/Zoom.js
Normal file
38
Python Version/DatamoshLib/FFG_effects/jscripts/Zoom.js
Normal 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;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Python Version/DatamoshLib/Original/classic.py
Normal file
35
Python Version/DatamoshLib/Original/classic.py
Normal 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)
|
||||
64
Python Version/DatamoshLib/Original/pymodes.py
Normal file
64
Python Version/DatamoshLib/Original/pymodes.py
Normal 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)
|
||||
|
||||
43
Python Version/DatamoshLib/Original/repeat.py
Normal file
43
Python Version/DatamoshLib/Original/repeat.py
Normal 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()
|
||||
21
Python Version/DatamoshLib/Tomato/LICENSE.txt
Normal file
21
Python Version/DatamoshLib/Tomato/LICENSE.txt
Normal 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.
|
||||
234
Python Version/DatamoshLib/Tomato/tomato.py
Normal file
234
Python Version/DatamoshLib/Tomato/tomato.py
Normal 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)))
|
||||
Reference in New Issue
Block a user