Moviepy freezes after first couple of frames after concatenation - python

I have been trying to build a project in which a Flask Application can automatically concatenate a selected amount of video's to a 'core video'.
User's can upload a video, which is sent to amazon s3 for storage.
All video's are preprocessed by Moviepy to be an mp4 file, running on 24 fps without audio, with a resolution of 720p.
After this preprocessing, the video is uploaded to amazon s3.
Of all new uploads in s3, a queue is created which an administrator can approve or delete.
All approved video's end up in a list that is concatenated with a current 'core video'.
This is done by using Pythons Moviepy library.
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip
videos_to_concat(VideoFileClip(core_video.s3_link))
for video in approved_videos:
videos_to_concat.append(VideoFileClip(video.s3_link))
result = concatenate_videoclips(videos_to_concat, method=compose)
Later, some audio is added under the full duration of the video.
result_with_audio = result.set_audio(some_audio.mp3)
The problem however, is that without throwing any errors, some videos are frozen after the first couple of frames after concatenation has been successfull. A frame remains stationary for the duration of the original clip. The audio keeps playing though. When a next clip is loaded, that one either plays normally or has the same behaviour of freezing after a couple of frames. There seems to be no obvious patern.
Initially I thought the mistake might be that ffmpeg does not download video's from the normal s3 link properly, but that would not explain why the the biggest video in the beginning and some other video's get rendered correctly, and some others aren't.
Could it that this is caused by a potential difference in codecs? (libx264 vs. mpeg4)?
Or is this way of accessing the files by URL and then directly feeding that to moviepy a potential cause of troubles? (VideoFileClip(https://amazon.s3.link.to.file.here.mp4)
Should I try to download all files and then locally concatenating them, or am I right to assume that the current approach should work.
When inspecting the files, nothing obvious like filename, filetype, resolution seems to be the issue, the preprocessing seems to do what it should.
Would love to hear any idea's on how the corruption of the resulting concatenated video could be explained and hopefully resolved.

Okay, I did manage to figure it out in the end. The problem was solved by downloading all video's with the boto3 client that amazon s3 provides for Python. Once downloading all video's to local storage of the webserver, concatenation worked without any issues.
I'm guessing that this might have something to do with s3 not serving the entire video file instantly through the link. In the end it seems quite logical to just use the provided s3 client to download store video's before performing any edits with moviepy.

Related

Reducing audio , video size on upload Django

I got a test server where I have features like uploading audio and video on a post . The feature is working perfectly but using a lot of space as some videos has more than 80MB while my system has only 1Gb of storage. How can I reduce my audio video size on upload maintaining no upload restriction. I am using Django and drf on backend . I looked into ffmpeg & pydub but couldnt find anything to reduce the audio bitrate or video quality. Is there anything else I should look into ? or ffmpeg will work (if ffmpeg works, please give me some example links so that I can implement before integrating to my test server) Thanks
Any suggestion regarding this will be helpful

Uploading an image to S3 and manipulating with Python in Lambda - best practice

I'm building my first web application and I've got a question around process and best practice, I'm hoping the expertise on this website might be give me a bit of direction.
Essentially, all the MVP is doing is going to be writing an overlay onto an image and presenting this back to the user, as follows;
User uploads picture via web form (into AWS S3) - to do
Python script executes (in lambda) and creates image overlay, saves new image back into S3 - complete
User is presented back with new image to download - to do
I've been running this locally as sort of a proof of concept and was planning on linking up with S3 today but then suddenly realised, what happens when there are two concurrent users and two images being uploaded with different filenames with two separate lambda functions working?
The only solution I could think of is having the image renamed upon upload with a record inserted into an RDS, then the lambda function to run upon record insertion against the new image, which would resolve half of it, but then how would I get the correct image relayed back to the user?
I'll be clear, I have next to no experience in web development, I want the front end to be as dumb as possible and run everything in Python (I'm a data scientist, I can write Python for data analysis but no experience as a software dev!)
You don't really need an RDS, just invoke your lambda synchronously from the browser.
So
Upload file to S3, using a randomized file name
Invoke your lambda synchronously, passing it the file name
Have your lambda read the file, convert it, and respond with either the file itself (binary responses aren't trivial), or a path to the converted file in S3.

Python get Audio/Video frames separately from video file

What i'm trying to do:
Hi!
I'm trying to store the Video and Audio information from a video file. I would like to store video frames and audio frames separately in different variables.
My intention is to manage video/files and do some actions with the audio and video frame list, but to do what I'm plannign to do I need to store this audio/video frames separately. I've read a lot of questions in StackOverflow about python and audio/video managing.
Most people recommend to use OpenCV or ffmpeg to manage videos. I saw some scripts using these libraries to get video(only video) frames, but none of them are getting audio, most of them are just getting video frames and save them as RGB images. I also check some scripts where people get audio frames from a mp3 file, but I'm not sure if you can do that in a video file
Most important thing to me is to know the best way to manage video and audio separately. I'm not looking for people to do my code, just asking to point me in a good direction.
One of the things I'm trying to do is to send this information via socket, but as I said I need the audio and video frames to be in separated variables (yes, i'm wondering about an stream app, but that's not the only thing I'm trying to do)
I know I should give more information, and maybe show some code, but I don't have any concret code I tried some things, but I've never been capable to separate audio and video. I know that each format has his own encryption, and at the end I decided to use "mp4" as video format but I don't know neither if this is the best format for what I'm trying to do.
Resume:
Is openCV the best way to manage video and audio separately ?
Wich is the easiest way to separate video and audio frames ? Is it possible ?
Wich is the best documentation I should read to learn about video/audio management ?
I would like to do the things with my own code, and use in the less way possible openCV or other libraries.
My "basic" idea is to get a "list" of audio and video frames, and then I would like to do some operations, but right now I can't find the best way for me to manage a vide using python. I even wonder if could be possible to manage a video as raw data
I need to know wich is the best library to manage videos using python, for me the best library, will be the one that allows me to manage the videos more "freely"
I've already checked:
I've read too many questions on this theme, the most recent are :
How to extract audio from video file
Split audio video separately from given video using MLT
Embed audio video in python gui

How do I get all the urls of a video flv pieces only with Python?

The url for ordinary people to watch the video is: http://v.youku.com/v_show/id_XNjM5NDU1OTUy.html
This video is split into 14 flv pieces, 5 of which are advertising flvs.
If I open the Developer Tools of IE11 and keep capturing the network flow during the whole process of watching the video (It must be the whole process, or the server doesn't send all of the video flv urls to IE11), the flv urls will be captured by IE11 and then I can copy the data of the flv urls which the below picture displays in a red line box:
Then I can change the data into a list of url-strings and use Python to download them.
But this is really trouble.
I have tried to match the source code of http://v.youku.com/v_show/id_XNjM5NDU1OTUy.html with the flv urls, but no results. So I guess there must be a function or a javascript or something else in the code to tell the server to send all the flv urls. Am I right?
So,
1.How to get all the urls of a video flv pieces only with Python?
2.What should I learn to solve this kind of problem.
After all, using Developer Tools of IE11, waiting for the whole process of the video (nearly one hour), copying the related data to a txt file and finally using Python to parse the txt file are really something trouble.
Thanks in advance.
I think you could get some insights from Youtube-dl. It is a set of python scripts created to "download Youtube videos and a few more sites". Go to their Download section and get the full source tarball. I think that could be useful in some way, at least to give you some directions on how to deal with flv pieces.

Accessing Video Data with Python

Question
How can I take a small sample of streamed frames, and manipulate them using Python? Are there any available libraries to use, or will I have to code the entire project alone?
Tech Specs
OS: Linux
Connection: CAT-5 Ethernet
Camera: dlink DCS-930L
Introduction
I recently asked a question, but it was closed because of clarity issues.
I am re-posting with many more details, and if it is still not clear, feel free to edit or add comments.
Background
I have a dlink DCS-930L camera which is directly connected to my Linux computer with a direct cat5 connection. I assigned it to a static IP adress, and everything works great.
When I open a web-browser, and connect to this static IP address (e.g. log into 192.168.0.20), the camera just works correctly in real time.
I did this was to verify that my camera was working, and that I was able to establish the Ethernet connection correctly.
Now, what I need to do some image processing on the video frames that I receive over the Ethernet from the camera.
I don't want to use the web-browser anymore as a means of display, and instead, I want to use Python to read the frames.
In other words, let's say that the camera produces 30 frames/second, and each frame has a certain size (e.g 1920x1080 pixels).
All I want to do is to start reading these frames in by Python. I don't mind if I am missing frames and if I am processing it slowly. Even if I am able to process one frame over a few seconds, I am still okay with that.
Since video is a collection of images (in this case 30 images per second), I want to be able to read these images using Python, and then be able to do whatever processing that I need to do on these images.
If I had these images saved on the computer, I would open these images with Python, and start to manipulate them. But, since in this case, the images are in fact being streamed, I just want to know how can I sample them (maybe one every few second), and do some manipulation using Python?
Please let me know if my question is still unclear, and I will try to clarify it as much as I can.
Thanks,
--Rudy
According to the manual, the camera serves video through a java applet, so that is will bedifficult to access through python without understanding that server protocol.
However, it does have an option to push images to at ftp server (page 34), so if you install vsftpd on your linux box, you can tell the camera to push images there at maybe as high as 4 fps. There are instructions on setting up vsftpd on ubuntu here, other versions of linux will be similar (I seem to remember fedora needing slightly less setup, but that was years ago).
You will need to enable uploads with the line write_enable=YES in /etc/vsftpd.conf. There are various ways to handle the uploads, the simplest one would be to have it log in with your user account, it will then dump images in your home directory (or a path you specify in the camera config).
You should then be able to open the images normally, ie with PIL.
If you don't want to set up a fileserver, you can try grabbing data directly with urllib2, see this page for how to handle the login. There is some chance by fooling around with fetching data you will be able to extract a video stream, but I think the ftp option will be a lot easier.
I am not familiar with exactly how the dlink DCS-30 works, but I have an earlier-generation model, the dlink DCS-20, and had the same objective, so maybe you can leverage my DCS-20 solution, or parts of it, to solve same for the DCS-30.
The key was just parsing the HTML provided by the built-in web browser access.
External modules requests, PIL, and BeautifulSoup simplify the solution.
Assuming your camera IP is 192.168.0.20, and that you've set up via the webadmin a user login to the camera of user1/pw1, here's the crux of the solution:
from StringIO import StringIO
import requests
from PIL import Image
from bs4 import BeautifulSoup
DCS_IP = "192.168.0.20"
userauth = ('user1', 'pw1')
snapurl = "http://" + DCS_IP + "/top.htm"
r = requests.get(snapurl, auth=userauth)
soup = BeautifulSoup(r.content)
# There are several <img> tags in page, so use border=0 attribute of
# objective <img> to distinguish it
imgtag = soup.find_all("img", attrs={'border':0})
imgsrc = BeautifulSoup(str(imgtag[0])).img['src']
imgurl = "http://" + DCS_IP + "/" + imgsrc
img = requests.get(imgurl, auth=userauth)
i = Image.open(StringIO(img.content))
i.save("snapshot.png")
Once you've retrieved the image (i), you can manipulate further with PIL, or, afterwards, use ffmpeg to, for example, stitch resulting image set into a time-lapse video.
HTH

Categories