I have written applications and scripts in the following languages:
Fortran, Java, Javascript, Basica, Visual Basic, Win32 Assembly, c, PHP and recently Python.
This small application to view 2D videos in 3D in realtime was originally written in c, but I have recently ported it to Python, which is what I will discuss today.
This is done with the aid of the freeware application Avisynth.
Avisynth is a video editing application that runs from user created scripts, which have the avs extension. Together with other applications such as Videodubmod, it can edit videos and save them as new videos. However, certain multimedia players can play a script as if it were a video, and so view the modified video as if it were a new video, with no actual change having been made to the video.
There are a couple of caveats however. The video must be an avi video and to assure the sound is synchronized, it must be at 25fps.
Mutimedia players that will play avs scripts are Media Player Classic, MPlayer, Zoom Player and Windows Media Player.
Below is an example of a public domain video that was spontaneously viewed in 3D. I did a screen capture and converted the snippet to an animated GIF for viewing on this site.
Click image for full size
Below is a view of the GUI
Click image to view full size
To run, just choose the player you want and then the type of 3D. On clicking the type, a folder dialog will open and after choosing the folder, a file dialog will open for the selected folder. Choosing a file will then open the chosen player and play the file in the selected 3D.
The type options are Crossed (side-by-side crossed), Parallel (side-by-side parallel), R-B (anaglyph – red left cyan right), B-Y (anaglyph – blue left yellow right), B-R (anaglyph – cyan left red right), and Y-B (anaglyph – yellow left blue right). The first two can be viewed without glasses, while the anaglyphs require the porper glasses.
The code is listed below:
import os
import subprocess
import tkinter
from tkinter import *
from tkinter import filedialog
def callback() :
odir = os.getcwd()
dirname = filedialog.askdirectory()
os.chdir(dirname)
filename = filedialog.askopenfilename()
a = filename.rfind(“/”) + 1
filename2 = filename[a: -4]
if os.name == ‘nt’ :
filename = filename.replace(“/”, “\\”)
fpsstr = ” fps=25, ConvertFPS=True”
syncstr = “”
if type.get() == “C” :
filestr = ‘a = DirectShowSource(“‘ + filename + ‘” , ‘ + fpsstr + ‘).ConvertToYUY2’ + syncstr + ‘ a1 = Crop(a,46,0,0,0) a2 = Crop(a,0,0,-46,0) StackHorizontal(a1,a2)’
elif type.get() == “P” :
filestr = ‘a = DirectShowSource(“‘ + filename + ‘” , ‘ + fpsstr + ‘).ConvertToYUY2’ + syncstr + ‘ a1 = Crop(a,46,0,0,0) a2 = Crop(a,0,0,-46,0) StackHorizontal(a2,a1)’
elif type.get() == “RB” :
filestr = ‘a = DirectShowSource(“‘ + filename + ‘” , ‘ + fpsstr + ‘)’ + syncstr + ‘a1 = Width(a) >= 600 ? Crop(a,64,0,0,0) : Crop(a,32,0,0,0) a1 = Tweak(a1, bright = 0, cont = 1.5) a2 = Width(a) >= 600 ? Crop(a,0,0,-64,0) : Crop(a,0,0,-32,0)a2 = Tweak(a2, bright = 0, cont = 1.5) ConvertToRGB32(a1)’ + syncstr + ‘a1 = RGBAdjust(r=1.0,g=0.0,b=0.0) ConvertToRGB32(a2) a2 = RGBAdjust(r=0.0,g=1.0,b=1.0) Merge(a1,a2,0.5)’
elif type.get() == “BY” :
filestr = ‘a = DirectShowSource(“‘ + filename + ‘” , ‘ + fpsstr + ‘)’ + syncstr + ‘a1 = Width(a) >= 600 ? Crop(a,64,0,0,0) : Crop(a,32,0,0,0) a1 = Tweak(a1, bright = 0, cont = 1.5) a2 = Width(a) >= 600 ? Crop(a,0,0,-64,0) : Crop(a,0,0,-32,0) a2 = Tweak(a2, bright = 0, cont = 1.5) ConvertToRGB32(a1) a1 = RGBAdjust(r=1.0,g=1.0,b=0.0) ConvertToRGB32(a2) a2 = RGBAdjust(r=0.0,g=0.0,b=1.0) Merge(a1,a2,0.5)’
elif type.get() == “BR” :
filestr = ‘a = DirectShowSource(“‘ + filename + ‘” , ‘ + fpsstr + ‘)’ + syncstr + ‘a1 = Width(a) >= 600 ? Crop(a,64,0,0,0) : Crop(a,32,0,0,0) a1 = Tweak(a1, bright = 0, cont = 1.5) a2 = Width(a) >= 600 ? Crop(a,0,0,-64,0) : Crop(a,0,0,-32,0) a2 = Tweak(a2, bright = 0, cont = 1.5) ConvertToRGB32(a1) a1 = RGBAdjust(r=1.0,g=0.0,b=0.0) ConvertToRGB32(a2) a2 = RGBAdjust(r=0.0,g=1.0,b=1.0) Merge(a2,a1,0.5)’
elif type.get() == “YB” :
filestr = ‘a = DirectShowSource(“‘ + filename + ‘” , ‘ + fpsstr + ‘)’ + syncstr + ‘a1 = Width(a) >= 600 ? Crop(a,64,0,0,0) : Crop(a,32,0,0,0) a1 = Tweak(a1, bright = 1.5, cont = 1.5, sat=2.0) a2 = Width(a) >= 600 ? Crop(a,0,0,-64,0) : Crop(a,0,0,-32,0) a2 = Tweak(a2, bright = 1.5, cont = 1.5, sat=2.0) ConvertToRGB32(a1) a1 = RGBAdjust(r=1.0,g=1.0,b=0.8) ConvertToRGB32(a2) a2 =RGBAdjust(r=0.0,g=0.0,b=0.2) Merge(a2,a1,0.5)’if player.get() == “MPC” :
appstr = “mplayerc.exe”
elif player.get() == “MP” :
appstr = “mplayer.exe”
elif player.get() == “WMP” :
appstr = “wmplayer.exe”
elif player.get() == “Zoom” :
appstr = “zplayer.exe”outputstr = odir + “/” + filename2 + “.avs”
if os.name == ‘nt’ :
outputstr = outputstr.replace(“/”, “\\”)
print(filename)
print(outputstr)
os.chdir(odir)
f = open(outputstr, ‘w’)
f.write(filestr)
f.close
subprocess.Popen([appstr, outputstr])window = tkinter.Tk()
window.title(“3dConversion”)
window.geometry(“360×480”)
text1 = “Player ”
text2 = “3d-Type ”
label1 = Label(window, text=text1, anchor=W, justify=LEFT)
player=StringVar()
r1 = Radiobutton(window, text=”MediaPlayer Classic “, variable = player, value=”MPC”)
r2 = Radiobutton(window, text=”MPlayer “, variable = player, value=”MP”)
r3 = Radiobutton(window, text=”Windows Media Player “, variable = player, value=”WMP”)
r4 = Radiobutton(window, text=”Zoom Player “, variable = player, value=”Zoom”)
label2 = Label(window, text=text2, anchor=W, justify=LEFT)
type=StringVar()
r5 = Radiobutton(window, text=”Crossed “, variable = type, value=”C”, command=callback)
r6 = Radiobutton(window, text=”Parallel “, variable = type, value=”P”, command=callback)
r7 = Radiobutton(window, text=”R-B “, variable = type, value=”RB”, command=callback)
r8 = Radiobutton(window, text=”B-Y “, variable = type, value=”BY”, command=callback)
r9 = Radiobutton(window, text=”B-R “, variable = type, value=”BR”, command=callback)
r10 = Radiobutton(window, text=”Y-B “, variable = type, value=”YB”, command=callback)
label1.grid(row=0, column=0)
r1.grid(row=1, column=0)
r2.grid(row=2, column=0)
r3.grid(row=3, column=0)
r4.grid(row=4, column=0)
label2.grid(row=5, column=0)
r5.grid(row=6, column=0)
r6.grid(row=7, column=0)
r7.grid(row=8, column=0)
r8.grid(row=9, column=0)
r9.grid(row=10, column=0)
r10.grid(row=11, column=0)
window.mainloop()
The first part imports necessary modules.
The second part saves the application directory in a variable, chooses a folder and then the video file path, gets the file name and converts the slashes for windows, if it is to be viewed there.
odir = os.getcwd()
dirname = filedialog.askdirectory()
os.chdir(dirname)
filename = filedialog.askopenfilename()
a = filename.rfind("/") + 1
filename2 = filename[a: -4]
if os.name == 'nt' :
filename = filename.replace("/", "\\")
The next code creates the script strings for the various types of 3D
if type.get() == "C" :
filestr = 'a = DirectShowSource("' + filename + '" , ' + fpsstr + ').ConvertToYUY2' + syncstr + ' a1 = Crop(a,46,0,0,0) a2 = Crop(a,0,0,-46,0) StackHorizontal(a1,a2)'
elif type.get() == "P" :
filestr = 'a = DirectShowSource("' + filename + '" , ' + fpsstr + ').ConvertToYUY2' + syncstr + ' a1 = Crop(a,46,0,0,0) a2 = Crop(a,0,0,-46,0) StackHorizontal(a2,a1)'
The next code sets up the player, creates the avs file and writes to it.
if player.get() == "MPC" :
appstr = "mplayerc.exe"
elif player.get() == "MP" :
appstr = "mplayer.exe"
elif player.get() == "WMP" :
appstr = "wmplayer.exe"
elif player.get() == "Zoom" :
appstr = "zplayer.exe"outputstr = odir + "/" + filename2 + ".avs"
if os.name == 'nt' :
outputstr = outputstr.replace("/", "\\")
print(filename)
print(outputstr)
os.chdir(odir)
f = open(outputstr, 'w')
f.write(filestr)
f.close
subprocess.Popen([appstr, outputstr])
;
The final code sets up the GUI
window = tkinter.Tk()
window.title("3dConversion")
window.geometry("360x480")
text1 = "Player "
text2 = "3d-Type "
label1 = Label(window, text=text1, anchor=W, justify=LEFT)
player=StringVar()
r1 = Radiobutton(window, text="MediaPlayer Classic ", variable = player, value="MPC")
r2 = Radiobutton(window, text="MPlayer ", variable = player, value="MP")
r3 = Radiobutton(window, text="Windows Media Player ", variable = player, value="WMP")
r4 = Radiobutton(window, text="Zoom Player ", variable = player, value="Zoom")
label2 = Label(window, text=text2, anchor=W, justify=LEFT)
type=StringVar()
r5 = Radiobutton(window, text="Crossed ", variable = type, value="C", command=callback)
r6 = Radiobutton(window, text="Parallel ", variable = type, value="P", command=callback)
r7 = Radiobutton(window, text="R-B ", variable = type, value="RB", command=callback)
r8 = Radiobutton(window, text="B-Y ", variable = type, value="BY", command=callback)
r9 = Radiobutton(window, text="B-R ", variable = type, value="BR", command=callback)
r10 = Radiobutton(window, text="Y-B ", variable = type, value="YB", command=callback)
label1.grid(row=0, column=0)
r1.grid(row=1, column=0)
r2.grid(row=2, column=0)
r3.grid(row=3, column=0)
r4.grid(row=4, column=0)
label2.grid(row=5, column=0)
r5.grid(row=6, column=0)
r6.grid(row=7, column=0)
r7.grid(row=8, column=0)
r8.grid(row=9, column=0)
r9.grid(row=10, column=0)
r10.grid(row=11, column=0)
window.mainloop()
Here is how a created avs file appears:
a = DirectShowSource("G:\mediaplayer-viral\FLV\AVI\A-L\HouseonHauntedHill_xvid.avi" , fps=25, ConvertFPS=True)a1 = Width(a) >= 600 ? Crop(a,64,0,0,0) : Crop(a,32,0,0,0) a1 = Tweak(a1, bright = 0, cont = 1.5) a2 = Width(a) >= 600 ? Crop(a,0,0,-64,0) : Crop(a,0,0,-32,0) a2 = Tweak(a2, bright = 0, cont = 1.5) ConvertToRGB32(a1) a1 = RGBAdjust(r=1.0,g=0.0,b=0.0) ConvertToRGB32(a2) a2 = RGBAdjust(r=0.0,g=1.0,b=1.0) Merge(a2,a1,0.5)
This application was written in Python 3.3 and although i feel it will work for all Python 3 versions, I am not sure about Python 2. Python is free and versions can be installed for any os.