Skip to content

Instantly share code, notes, and snippets.

@eyaler
Last active March 30, 2023 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eyaler/9fa8596428bdeadb980e0ba7828f8a3b to your computer and use it in GitHub Desktop.
Save eyaler/9fa8596428bdeadb980e0ba7828f8a3b to your computer and use it in GitHub Desktop.
junkie.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "junkie.ipynb",
"provenance": [],
"private_outputs": true,
"collapsed_sections": [],
"machine_shape": "hm",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/eyaler/9fa8596428bdeadb980e0ba7828f8a3b/junkie.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jDk8HPugSgSR"
},
"source": [
"# A short-window cross-channel frame-shuffle junkie glitch effect\n",
"## By Eyal Gruss\n",
"### Inspired by Doron Adler\n",
"Shortcut to here: https://eyalgruss.com/junkie\n",
"\n",
"Text and video: https://dailypsychedelicvideo.com/2019/12/13/based-on-a-real-bug\n",
"\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "sqeR_WhOQDFc",
"cellView": "form"
},
"source": [
"#@title Optionally upload videos\n",
"from google.colab import files\n",
"import os\n",
"import shutil\n",
"\n",
"%cd /content\n",
"shutil.rmtree('input', ignore_errors=True)\n",
"os.makedirs('input')\n",
"%cd input\n",
"try:\n",
" files.upload()\n",
"except:\n",
" print('file upload timed out. please try again...') #due to https://github.com/googlecolab/colabtools/issues/467"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "PUgvlv3BS5CY",
"cellView": "form"
},
"source": [
"#@title Or paste a URL to an online (e.g. youtube) video:\n",
"import os\n",
"import shutil\n",
"\n",
"%cd /content\n",
"shutil.rmtree('input', ignore_errors=True)\n",
"os.makedirs('input')\n",
"%cd input\n",
"url = '' #@param {type:\"string\"}\n",
"!pip install -U git+https://github.com/ytdl-org/youtube-dl\n",
"!youtube-dl --no-playlist $url"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "fL2UosodVYcc",
"cellView": "form"
},
"source": [
"#@title Choose glitch options and run!\n",
"color_space = 'YCrCb' #@param ['RGB', 'YCrCb']\n",
"temporal_shuffle_mode = '123' #@param ['NONE', 'ALL', '23', '123']\n",
"temporal_shuffle_frames = 6 #@param {type:\"integer\"}\n",
"spatial_shift = 0 #@param {type:\"integer\"}\n",
"take_first_percent = 100 #@param {type:\"number\"}\n",
"assert temporal_shuffle_frames>0, 'temporal_shuffle_frames must be > 0'\n",
"assert 100>=take_first_percent>0, 'take_first_percent must be between 0 and 100'\n",
"\n",
"%cd /content\n",
"\n",
"from moviepy.editor import *\n",
"import random\n",
"import numpy as np\n",
"import cv2\n",
"\n",
"input_folder = 'input'\n",
"output_folder = 'output'\n",
"temp_folder = 'temp'\n",
"\n",
"os.makedirs(output_folder, exist_ok=True)\n",
"shutil.rmtree(temp_folder, ignore_errors=True)\n",
"for input_filename in os.listdir(input_folder):\n",
" print('\\n'+input_filename)\n",
" original_video = VideoFileClip(os.path.join(input_folder, input_filename))\n",
" if take_first_percent<100:\n",
" original_video = original_video.subclip(0, original_video.duration*take_first_percent/100)\n",
" print('fps=%.2f duration=%.2f'%(original_video.fps, original_video.duration))\n",
" clip_start = 0\n",
" j = 0\n",
" os.makedirs(temp_folder)\n",
" while clip_start < original_video.duration:\n",
" clip_end = min(clip_start + temporal_shuffle_frames/original_video.fps, original_video.duration)\n",
" clip = original_video.subclip(clip_start, clip_end)\n",
" frames = list(clip.iter_frames())[:temporal_shuffle_frames]\n",
" if spatial_shift > 0 or temporal_shuffle_mode!='NONE':\n",
" y = []\n",
" r = []\n",
" b = []\n",
" for i in range(len(frames)):\n",
" if color_space == 'RGB':\n",
" yrb = frames[i].copy()\n",
" elif color_space == 'YCrCb':\n",
" yrb = cv2.cvtColor(frames[i], cv2.COLOR_RGB2YCR_CB)\n",
" yrb[..., 1] = np.roll(yrb[..., 1], spatial_shift, axis=0)\n",
" yrb[..., 2] = np.roll(yrb[..., 2], spatial_shift, axis=1)\n",
" if temporal_shuffle_mode in ('23', '123'):\n",
" y.append(yrb[..., 0])\n",
" r.append(yrb[..., 1])\n",
" b.append(yrb[..., 2])\n",
" elif color_space == 'RGB':\n",
" frames[i] = yrb\n",
" elif color_space == 'YCrCb':\n",
" frames[i] = cv2.cvtColor(yrb, cv2.COLOR_YCR_CB2RGB)\n",
" if temporal_shuffle_mode in ('23', '123'):\n",
" if temporal_shuffle_mode == '123':\n",
" random.shuffle(y)\n",
" random.shuffle(r)\n",
" random.shuffle(b)\n",
" for i in range(len(frames)):\n",
" yrb = np.dstack((y[i], r[i], b[i]))\n",
" if color_space == 'RGB':\n",
" frames[i] = yrb\n",
" elif color_space == 'YCrCb':\n",
" frames[i] = cv2.cvtColor(yrb, cv2.COLOR_YCR_CB2RGB)\n",
" elif temporal_shuffle_mode == 'ALL':\n",
" random.shuffle(frames)\n",
" for frame in frames:\n",
" cv2.imwrite(os.path.join(temp_folder, '%06d.png'%j), frame[...,::-1])\n",
" j+=1\n",
" clip_start = clip_end\n",
" output_filename = os.path.join(output_folder, os.path.splitext(input_filename)[0] + '_' + color_space + '_' + temporal_shuffle_mode + '_sep%d' % spatial_shift+'.mp4')\n",
" try:\n",
" final_video = ImageSequenceClip(temp_folder, fps=original_video.fps)\n",
" final_video.audio = original_video.audio\n",
" final_video.write_videofile(output_filename, codec='libx264', audio_codec='aac')\n",
" except Exception as e:\n",
" print(e)\n",
" if os.path.exists(output_filename):\n",
" os.remove(output_filename)\n",
" shutil.rmtree(temp_folder)\n",
"\n",
"file = sorted([os.path.join(output_folder, file) for file in os.listdir(output_folder) if os.path.splitext(file)[1]=='.mp4'], key=os.path.getmtime)[-1]\n",
"print('playing: ' + file)\n",
"clip = VideoFileClip(file)\n",
"clip.ipython_display(height=512, autoplay=1, loop=1, maxduration=333)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "S6QwSg8mUbLa",
"cellView": "form"
},
"source": [
"#@title Download videos\n",
"print() #fix issue https://github.com/googlecolab/colabtools/issues/468\n",
"from google.colab import files\n",
"import time\n",
"%cd /content\n",
"output_folder = 'output'\n",
"output_files = sorted([os.path.join(output_folder, file) for file in os.listdir(output_folder) if os.path.splitext(file)[1]=='.mp4'], key=os.path.getmtime, reverse=True)\n",
"for file in output_files:\n",
" print('downloading: '+file)\n",
" try:\n",
" files.download(file)\n",
" except:\n",
" time.sleep(5)\n",
" try:\n",
" files.download(file)\n",
" except:\n",
" print('please try downloading again...') #may be due to https://github.com/googlecolab/colabtools/issues/34"
],
"execution_count": null,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment