How to convert video on python to .mp4 without ffmpeg? - python

I need to convert videos to .mp4 format I used to ffmpeg but it converts for too long. Is there are a way to convert video to .mp4 in python without ffmpeg?

UPD moviepy depends on ffmpeg too (
==
Zulko/moviepy
pip install MoviePy
import moviepy.editor as moviepy
clip = moviepy.VideoFileClip("myvideo.avi")
clip.write_videofile("myvideo.mp4")
As per MoviePy documentation, there is no ffmpeg dependencies:
MoviePy depends on the Python modules Numpy, imageio, Decorator, and tqdm, which will be automatically installed during MoviePy's installation.
ImageMagick is not strictly required, but needed if you want to incorporate texts. It can also be used as a backend for GIFs, though you can also create GIFs with MoviePy without ImageMagick.
PyGame is needed for video and sound previews (not relevant if you intend to work with MoviePy on a server but essential for advanced video editing by hand).
For advanced image processing, you will need one or several of the following packages:
The Python Imaging Library (PIL) or, even better, its branch Pillow.
Scipy (for tracking, segmenting, etc.) can be used to resize video clips if PIL and OpenCV are not installed.
Scikit Image may be needed for some advanced image manipulation.
OpenCV 2.4.6 or a more recent version (one that provides the package cv2) may be needed for some advanced image manipulation.
Matplotlib

I wrote a quick program that will convert all video files of a particular type in a directory to another type and put them in another directory.
I had to install moviepy using Homebrew for it to work rather than rely on PyCharm's package installation.
import moviepy.editor as moviepy
import os
FROM_EXT = "mkv"
TO_EXT = "mp4"
SOURCE_DIR = "/Volumes/Seagate Media/Movies/MKVs"
DEST_DIR = "/Volumes/Seagate Media/Movies/MP4s"
for file in os.listdir(SOURCE_DIR):
if file.lower().endswith(FROM_EXT.lower()):
from_path = os.path.join(SOURCE_DIR, file)
to_path = os.path.join(DEST_DIR, file.rsplit('.', 1)[0]) + '.' + TO_EXT
print(f"Converting {from_path} to {to_path}")
clip = moviepy.VideoFileClip(from_path)
clip.write_videofile(to_path)

Related

Moviepy distorting concatenated (portrait) videos

Trying to concatenate various "Portrait" videos I took with my mobile phone using the moviepy library. But for some reason, the result is a distorted video. As a TEST CASE, I have even tried to read JUST ONE video clip and re-write it using the concatenate_videoclips method and it still produces a distorted result.
Here is a sample frame from a test video taken with my mobile (resolution on disk: 1920 x 1080 which obviously includes the black background):
Here is the same frame captured from the output video (resolution maintained at 1920 x 1080 but without the black background => distorted image):
Here is the (very simple) code snippet I used:
from moviepy.editor import VideoFileClip, concatenate_videoclips
video_0 = VideoFileClip("test_vid.mp4")
concatenated_clip = concatenate_videoclips([video_0], method="compose") # same result if method="chain"
concatenated_clip.write_videofile("test_vid_concat.mp4")
I can't figure out what the issue is.
This is a bug in moviepy version 1.0.3: the ffmpeg reader doesn't take rotation metadata into account for videos captured on phones. The bug was noted in:
Video file clip width and height do not take rotation metadata into account #1663
and a fix provided in May of this year on the master branch:
Take into account rotation metadata to define video size #577
Version 1.0.3 is still the latest version on PyPI (i.e. version installed by pip), so you need to install the master branch (git clone the repo and run py setup.py install in the source folder) to get the fix.
I ran into the same issue and installing the master branch fixed it for me.
Be forewarned: moviepy is still pretty out of date. It relies on numpy == 1.20 and so you will have to use a lot of older packages. I highly recommend installing in a virtual environment.

How to render emojis as images in Python under Windows?

My goal is to generate (in Python under Windows) a bitmap image rendering any unicode character, including in particular emojis. I have installed several emoji-friendly fonts (including Symbola) for testing purpose.
So far I've tried PIL, matplotlib and pygame, but none of these are able to do it under Windows (the first two apparently can do it on some versions of Linux / MacOS, while pygame is explicitly limited to characters up to 0xffff, which rules out emojis).
I found that reportlab is able to generate a PDF with emojis (while its bitmap renderer fails to properly render them), but I still need to find a way to extract the emoji character from the PDF and convert it to bitmap. I feel like there has to be a simpler way...
NB: this question is related to Rendering Emoji with PIL but I do not necessarily want to use PIL if another library can do the job
I eventually found a solution in Is there any good python library for generating and rendering text in image format?. Although it is based on a third-party executable, as mentioned it is easy to wrap in Python.
Exact steps were as follows:
Install ImageMagick from https://www.imagemagick.org/script/download.php#windows
Set environment variable MAGICK_HOME to installation folder
Install Pillow to be able to manipulate easily the resulting image in Python (conda install pillow)
Download and install the Symbola font from https://fontlibrary.org/en/font/symbola
And my test script:
import os
import subprocess
import PIL.Image
to_render = '🤓'
output_file = 'rendered_emoji.bmp'
subprocess.run([
os.path.join(os.environ['MAGICK_HOME'], 'magick.exe'),
'convert', '-font', 'Symbola', '-size', '50x50',
'-gravity', 'center', f'label:{to_render}', output_file])
image = PIL.Image.open(output_file)
image.show()

Rotating a video with Python 3.4

I am using moviepy to try resize a video clip but every time I try I get this error. Can anyone explain how I can fix it? Thanks
My python code
Import everything needed to edit video clips
from moviepy.editor import *
# Load video clip
myclip = VideoFileClip("dog.mov")
myclip.resize( (460,720) ) # New resolution: (460,720)
myclip.write_videofile("resized_clip.mp4") #write new video file
The error
File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 699, in tostring
"Please call tobytes() instead.")
Exception: tostring() has been removed. Please call tobytes() instead.
Looks like you are using PIL, I would try using Pillow, a support fork that is maintained. MoviePY recommends you use Pillow in lieu of Pil in it's docs:
http://zulko.github.io/moviepy/install.html
For advanced image processing you will need one or several of these
packages. For instance using the method clip.resize requires that at
least one of Scipy, PIL, Pillow or OpenCV are installed.
The Python Imaging Library (PIL) or, better, its branch Pillow .

Recording video with webcam using VideoCapture

I want to record a video with python (using my webcam) and I came across VideoCapture which was easy to install on windows. I know there is OpenCV out there, but that was too much for me.
So far I can create every 0.04 seconds a .jpg with this code:
from VideoCapture import Device
import time
cam = Device(devnum=0) #uses the first webcame which is found
x = 0
while True:
cam.saveSnapshot(str(x)+'.jpg', timestamp=3, boldfont=1) #########################
x += 1
time.sleep(0.04)
0.04 seconds * 25 = 1. So what I am planning to do is an animated gif, that has 25 frames/sec. If somebody of you knows how to produce a real video file like .mp4, I really would prefer the .mp4 rather than .gif. However if thats not possible, the next thing I need to do is, to concatenate all .jpg files (0.jpg, 1.jpg, 2.jpg ...) but as you can imagine with increasing recording time I get A LOT of files. So I was wondering if it would be possible to write the .jpg files (the frames) to one .gif file consecutively. If thats not possible in python, how would you concatenate the jpg files to get an animated gif in the end?
OpenCV will make it more easy. You will find more problem in your method. To use opencv you have to install 1 more package known as numpy (numerical python). It's easy to install. If you want to install it automatically:
Install
Install pip manually
After that go to your cmd>python folder>Lib>site-packages and type pip install numpy *but for using pip you have to be in internet access.
After installation of numpy just type pip intall opencv.
Now you can import all the packages. If numpy somehow fails, maunually downlaod numpy 1.8.0 and install it.

How do I open .wmv files with OpenCV on Mac?

I am trying to open a Windows Media Video file on a macintosh using OpenCV. To view this video in MacOS I had to install a player called Flip4Mac. I am assuming that this came with the codecs for decoding WMV. Is there something I can now do to get OpenCV to open the videos using the codec?
In python/opencv2 opening a video should be super easy:
cap = cv2.VideoCapture('0009.wmv')
But I get this:
WARNING: Couldn't read movie file 0009.wmv
OpenCV video on OS X is very buggy in my experience. However try installing ffmpeg using Homebrew (I also recommend installing OpenCV using homebrew if you haven't done that already):
$ brew install ffmpeg
On Mavericks I've had all kinds of problems getting OpenCV and ffmpeg work together, so you might want to try installing ffmpeg and opencv in different orders, if this does not work. But for me now the following code works, provided that there is a file named test.wmv in the directory:
import cv2
vid = cv2.VideoCapture("test.wmv")
while True:
vid.grab()
retval, image = vid.retrieve()
if not retval:
break
cv2.imshow("Test", image)
cv2.waitKey(1)
I have had the problem before and it was simply that VideoCapture needed the full path to the file and not a relative path.
hope this helps.

Categories