mirror of
https://github.com/c0decracker/video-splitter.git
synced 2026-01-23 02:24:16 +00:00
Allow videos to split unevenly by providing a manifest.json file.
This commit is contained in:
parent
0f9bab380b
commit
2de78b03dc
3 changed files with 112 additions and 17 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1 +1,3 @@
|
|||
*.pyc
|
||||
*.mp4
|
||||
*example.json
|
||||
|
|
|
|||
41
README.md
41
README.md
|
|
@ -4,11 +4,50 @@ Simple command line Python script that splits video into multi chunks. Under the
|
|||
|
||||
Run `python ffmpeg-split.py -h` to see the options. Here are few samples of how it could be used:
|
||||
|
||||
## Spliting video into equal chunks
|
||||
|
||||
`python ffmpeg-split.py -f big_video_file.mp4 -s 10`
|
||||
|
||||
This splits `big_video_file.mp4` into 10 chunks. Each chunk will be suffixed with numeric index, for example `big_video_file-0.mp4`, `big_video_file-1.mp4`, etc.
|
||||
|
||||
## Splitting videos into unequal chunks
|
||||
|
||||
[FFMpeg]: https://www.ffmpeg.org/
|
||||
In order to create unequal chunks of a video, you'll need to create ***manifest.json*** :
|
||||
|
||||
```json
|
||||
|
||||
[
|
||||
{
|
||||
"start_time": 0,
|
||||
"length": 34,
|
||||
"rename_to": "video1"
|
||||
},
|
||||
{
|
||||
"start_time": 35,
|
||||
"length": 22,
|
||||
"rename_to": "video2.mp4"
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
Afterwards run:
|
||||
|
||||
`python ffmpeg-split.py -f big_video_file.mp4 -m manifest.json`
|
||||
|
||||
This splits `big_video_file.mp4` into 2 video files, video1.mp4 and video2.mp4. The video1.mp4 is a 34 seconds
|
||||
clip, starting from 0:00 to 0:34 of the `big_video_file.mp4`.
|
||||
|
||||
#### Manifest Options
|
||||
|
||||
* start_time - number of seconds into the video or start time
|
||||
* length - length of the video in seconds. The end time of the video is calculated by the start_time plus the length of the video.
|
||||
* rename_to - name of the video clip to be saved
|
||||
* end_time - end time of the video
|
||||
|
||||
|
||||
|
||||
|
||||
[FFMpeg]: https://www.ffmpeg.org/
|
||||
|
||||
|
||||
|
|
|
|||
86
ffmpeg-split.py
Executable file → Normal file
86
ffmpeg-split.py
Executable file → Normal file
|
|
@ -3,20 +3,69 @@
|
|||
import subprocess
|
||||
import re
|
||||
import math
|
||||
import json
|
||||
import os
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
length_regexp = 'Duration: (\d{2}):(\d{2}):(\d{2})\.\d+,'
|
||||
re_length = re.compile(length_regexp)
|
||||
|
||||
def main():
|
||||
def split_by_manifest(filename, manifest):
|
||||
if not os.path.exists(manifest):
|
||||
print "File does not exist: %s" % manifest
|
||||
raise SystemExit
|
||||
|
||||
(filename, split_length) = parse_options()
|
||||
if split_length <= 0:
|
||||
try:
|
||||
with open(manifest, "r") as manifest_file:
|
||||
config = json.load(manifest_file)
|
||||
except Exception as e:
|
||||
print e
|
||||
raise SystemExit
|
||||
|
||||
split_cmd = "ffmpeg -i '"+filename+"' -vcodec copy "
|
||||
split_count = 1
|
||||
split_error = []
|
||||
try:
|
||||
fileext = filename.split(".")[-1]
|
||||
except IndexError as e:
|
||||
raise IndexError("No . in filename. Error: " + str(e))
|
||||
|
||||
for video_config in config:
|
||||
split_str = ""
|
||||
try:
|
||||
split_start = video_config["start_time"]
|
||||
split_length = video_config.get("end_time", None)
|
||||
if not split_length:
|
||||
split_length = video_config["length"]
|
||||
filebase = video_config["rename_to"]
|
||||
if fileext in filebase:
|
||||
filebase = ".".join(filebase.split(".")[:-1])
|
||||
|
||||
split_str += " -ss " + str(split_start) + " -t " + \
|
||||
str(split_length) + \
|
||||
" '"+ filebase + "." + fileext + \
|
||||
"'"
|
||||
print "About to run: "+split_cmd+split_str
|
||||
output = subprocess.Popen(split_cmd+split_str,
|
||||
shell = True, stdout =
|
||||
subprocess.PIPE).stdout.read()
|
||||
except IndexError as e:
|
||||
print "############# Incorrect format ##############"
|
||||
print "The format of each json array should be:"
|
||||
print "{start_time: <int>, length: <int>, rename_to: <string>}"
|
||||
print "#############################################"
|
||||
print e
|
||||
raise SystemExit
|
||||
|
||||
|
||||
|
||||
def split_by_seconds(filename, split_length):
|
||||
if split_length and split_length <= 0:
|
||||
print "Split length can't be 0"
|
||||
raise SystemExit
|
||||
|
||||
output = subprocess.Popen("ffmpeg -i '"+filename+"' 2>&1 | grep 'Duration'",
|
||||
output = subprocess.Popen("ffmpeg -i '"+filename+"' 2>&1 | grep 'Duration'",
|
||||
shell = True,
|
||||
stdout = subprocess.PIPE
|
||||
).stdout.read()
|
||||
|
|
@ -30,7 +79,6 @@ def main():
|
|||
else:
|
||||
print "Can't determine video length."
|
||||
raise SystemExit
|
||||
|
||||
split_count = int(math.ceil(video_length/float(split_length)))
|
||||
if(split_count == 1):
|
||||
print "Video length is less then the target split length."
|
||||
|
|
@ -48,7 +96,7 @@ def main():
|
|||
split_start = 0
|
||||
else:
|
||||
split_start = split_length * n
|
||||
|
||||
|
||||
split_str += " -ss "+str(split_start)+" -t "+str(split_length) + \
|
||||
" '"+filebase + "-" + str(n) + "." + fileext + \
|
||||
"'"
|
||||
|
|
@ -57,34 +105,40 @@ def main():
|
|||
subprocess.PIPE).stdout.read()
|
||||
|
||||
|
||||
def parse_options():
|
||||
parser = OptionParser()
|
||||
|
||||
def main():
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option("-f", "--file",
|
||||
dest = "filename",
|
||||
help = "file to split, for example sample.avi",
|
||||
help = "File to split, for example sample.avi",
|
||||
type = "string",
|
||||
action = "store"
|
||||
)
|
||||
parser.add_option("-s", "--split-size",
|
||||
dest = "split_size",
|
||||
help = "split or chunk size in seconds, for example 10",
|
||||
help = "Split or chunk size in seconds, for example 10",
|
||||
type = "int",
|
||||
action = "store"
|
||||
)
|
||||
parser.add_option("-m", "--manifest",
|
||||
dest = "manifest",
|
||||
help = "Split video based on a json manifest file. ",
|
||||
type = "string",
|
||||
action = "store"
|
||||
)
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
|
||||
if options.filename and options.split_size:
|
||||
|
||||
return (options.filename, options.split_size)
|
||||
|
||||
split_by_seconds(options.filename, options.split_size)
|
||||
elif options.filename and options.manifest:
|
||||
split_by_manifest(options.filename, options.manifest)
|
||||
else:
|
||||
parser.print_help()
|
||||
raise SystemExit
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
try:
|
||||
try:
|
||||
main()
|
||||
except Exception, e:
|
||||
print "Exception occured running main():"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue