0

I need to use a device formatted in FAT32 to store/share movies (Using my routers filesharing feature. Unfortunately, my router doesn't support ExFat, only FAT32.). FAT32 has a limit for how big files can be, 4 GB. One hour BD is typically 4,5 GB so I have a problem here.

However, VLC seems to support seamless playback of files if they are numbered (at least a movie I had that came on two CDs Movie CD1.avi and Movie CD2.avi worked fine) so my plan was to simply split my too big files in parts slightly smaller than 4 GB. Since I don't need to re-encode or so it should be reasonably quick.

I read this question about using Handbrake to trim videos, but that is not exactly what I want to do. I want to tell Handbrake, or any other similar software (preferably available in Mac version but I have access to Win7 and Linux too) "split this 10 GB MKV into as many MKVs necessary that are max 3,5 GB" (e.g. 2 x 3,5 GB and 1 x 3 GB, Movie1.mkv, Movie2.mkv, Movie3.mkv).

Is there an easy way to accomplish this in Handbrake (or some other software)?

d-b
  • 636
  • 1
  • 6
  • 24
  • You cannot reliably do this, as the file size is not a function of duration alone, but also depends on the way the video was encoded. So you won't know how many minutes each part has to be in order for it to have a certain file size. If it works (cannot test now) you could simply split the binary files with the `split` utility, for example. – slhck Mar 18 '20 at 17:17
  • @slhck It doesn't really matter if the file becomes 3,8 or 3,9 GB. – d-b Mar 19 '20 at 07:57

1 Answers1

2

Here is a simple program using python. FFmpeg and FFprobe

Short description. Program takes single input 'filename'. For brevity there is minimal error checking. Edit the script to set your desired threshold before segmenting, segment extension (commonly 'part','cd','disk')

It does not re-encode just remuxes into equal length (duration) segments.

Default ouputs are 'filename.part#.mkv'

import os, sys, subprocess

fthreshMB = 3900 # threshhold size in MB
fthresh = fthreshMB * 1024*1024
segext = '.part'
segstartnum = 1

# main
fp = sys.argv[1]
if not os.path.isfile(fp):
    print('Invalid file',fp)
    sys.exit(1)

fsize = os.path.getsize(fp)
if fsize < fthresh:
    print('File is below threshhold of',fthreshMB,'MB')
    sys.exit(0)
    
# get file duration
ffcmd = 'ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "' + fp + '"'
result = subprocess.run(ffcmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
fdur = float(result.stdout)

# number of segments
segs = 1
while (fsize / segs) > fthresh:
    segs += 1
segdur = int(fdur / segs)
print('duration',fdur,'seconds. divide into',segs,'segments of',segdur,'seconds. segment start number',segstartnum)

# split file
fn, fext = os.path.splitext(fp)
ffcmd = 'ffmpeg -hide_banner -y -i "' + fp + '" -c copy -map 0 -segment_time ' + str(segdur) + ' -f segment ' + \
        '-reset_timestamps 1 -segment_start_number ' + str(segstartnum) + ' "' + fn + segext + '%d' + fext + '"'
result = subprocess.run(ffcmd,capture_output=True)
if result.returncode == 0: print('success')
else: print('error')
at2010
  • 104
  • 5