While recording my screen with OBS capture, I accumulated large quantity of videos that had been subject to a forced system shutdown, leaving them unfinalized. The videos were created using an .flv format, so when I play them in VLC Player they play flawlessly, however they are missing an end time (video length). Instead, the videos show the running time as they play, but maintain the 00:00 end time, despite the actual video playing for several minutes.
From my understanding, unlike .mp4 formatting, .flv formatted video should be able to be recovered if it has not been finalized (as in the case of my footage stopped by unexpected shutdowns). Since I have a large quantity of unfinalized, I need an automated solution to fix them.
write_videofile
I attempted to fix the videos by using the MoviePy write_videofile
command in the python shell with the directory set to the directory of the bad video:
from moviepy.editor import * #no error
vid = VideoFileClip("oldVideoName.flv") #no error
vid.write_videofile("corrected.mp4") #IndexError
The final line created breifly created a file "correctedTEMP_MPY_wvf_snd.mp3"(only 1KB, unplayable in Audacity), shorty before throwing an exception. I recieved a massive traceback with the final teir reading:
File "\Python37-32\lib\site-packages\moviepy\audio\io\readers.py", line 168, in get_frame
"Accessing time t=%.02f-%.02f seconds, "%(tt[0], tt[-1])+
IndexError: index 0 is out of bounds for axis 0 with size 0
I assumed that this was caused by a problem with an audio reader not accepting the supposed 00:00 timestamp as the length of the video.
subclip
I attempted to see if there was a way that I could manually feed MoviePy the start and end timestamps, using the subclip
method. I know the video is at least 4 seconds long, so I used that as a control test:
clip = vid.subclip("00:00:00", "00:00:05") #no error
clip.write_videofile("corrected.mp4") #OSError
The write_videofile method again threw an exception:
File "\Python37-32\lib\site-packages\moviepy\audio\io\readers.py", line 169, in get_frame
"with clip duration=%d seconds, "%self.duration)
OSError: Error in file oldVideoName.flv,
Accessing time t=0.00-0.04 seconds, with clip duration=0 seconds,
Even if this method were to work, I would need to find a way to automate the process of discovering the video end time.
CAP_PROP_FRAME_COUNT
One possible solution to finding the end time (video length) is to use cv2, per this post.
import cv2 #no error
vid=cv2.VideoCapture("oldVideoName.flv") #no error
vid.get(cv2.CAP_PROP_FRAME_COUNT) #returns -5.534023222112865e+17
I was not expecting to receive a negative float for this value. Further tests reveal to me that this float does not correspond at all with the length of the video, as all unfinalized videos return the same float for this request. (Normal videos do return their length for this method call) This is useful to iterate over a directory identifying unfinalized videos.
Is using MoviePy to correct a large quantity of unfinalized videos a viable or even possible solution? Is it better to use cv2 (Python OpenCV) for solving this problem?
I was able to fix the video files using yamdi, an open source metadata injector for FLV files. After downloading and installing yamdi, I can use the following command to repair an .flv file named oldVideoName.flv
:
yamdi -i oldVideoName.flv -o corrected.flv
The command leaves oldVideoName.flv
untouched, and saves a repaired file as corrected.flv
.