Skip to content

mkvmerge could not be found on system error message when set_duration is large, works fine when set_duration is small #164

@alexboydray

Description

@alexboydray

Bug/Issue Description:
Please note I have found a workaround for this problem, but thought I would mention it just in case it was something to add to documentation for others.
When attempting to split relatively long movie (2h 04m 27s) using python API, execution of python program fails when attempting to split_video_mkvmerge method, citing error ERROR:root:mkvmerge could not be found on the system. Please install mkvmerge to enable video output support. Plus additional error lines that can be seen below.

When the duration is decreased on the video_manager (tested a 20 second duration) the split_video_mkvmerge method works fine. Furthermore, the output of the is_mkvmerge_available() shows as True.

Here are the contents of the two python files:

main.py

import VideoSplitter

if __name__ == "__main__":
    VideoSplitter.videoSplitter("[1988] Akira (24 FPS).mkv")

VideoSplitter.py

from __future__ import print_function
import os
import subprocess
import scenedetect
from math import ceil
from scenedetect.video_manager import VideoManager
from scenedetect.frame_timecode import FrameTimecode
from scenedetect.detectors import ContentDetector
from scenedetect.scene_detector import SceneDetector
from scenedetect.stats_manager import StatsManager
from scenedetect.scene_manager import SceneManager
from scenedetect import video_splitter


def videoSplitter(media_name):

    video_manager = VideoManager([media_name], framerate=24.0)
    scene_manager = SceneManager()

    scene_manager.add_detector(ContentDetector(threshold=27.0))
    base_timecode = video_manager.get_base_timecode()

    try:
        media_length = float(ceil(get_length(media_name)))

        start_time = base_timecode
        end_time = base_timecode + media_length  # full length of movie in seconds

        # Set video_manager duration to read frames from 00:00:00 until end of movie
        video_manager.set_duration(start_time=start_time, end_time=end_time)

        # Set downscale factor to improve processing speed (no args means default).
        video_manager.set_downscale_factor()

        # Start video_manager.
        video_manager.start()

        # Perform scene detection on video_manager.
        scene_manager.detect_scenes(frame_source=video_manager)

        # Obtain list of detected scenes.
        scene_list = scene_manager.get_scene_list(base_timecode)

        # Like FrameTimecodes, each scene in the scene_list can be sorted if the
        # list of scenes becomes unsorted.

        print(
            "Is MKVMerge Available: {0}".format(
                scenedetect.video_splitter.is_mkvmerge_available()
            )
        )
        print("Number of scenes detected: {0}".format(len(scene_list)))

        scenedetect.video_splitter.split_video_mkvmerge(
            [media_name],
            scene_list,
            "Scenes\\Scene.mkv",
            media_name.split(".")[0],
            suppress_output=False,
        )

    finally:
        video_manager.release()


def get_length(filename):
    result = subprocess.run(
        [
            "ffprobe",
            "-v",
            "error",
            "-show_entries",
            "format=duration",
            "-of",
            "default=noprint_wrappers=1:nokey=1",
            filename,
        ],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
    )
    return float(result.stdout)

Error Received after running main.py

**100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 179020/179020 [25:33<00:00, 116.72frames/s] 
Is MKVMerge Available: True
Number of scenes detected: 4321
ERROR:root:mkvmerge could not be found on the system. Please install mkvmerge to enable video output support.
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    VideoSplitter.videoSplitter("[1988] Akira (24 FPS).mkv")
  File "C:\Users\Alex\Projects\Non-School Related Projects\Modern-Love\Modern-Love-Video-Splitter\VideoSplitter.py", line 60, in videoSplitter
    scenedetect.video_splitter.split_video_mkvmerge(
  File "C:\Python38-64\lib\site-packages\scenedetect\video_splitter.py", line 163, in split_video_mkvmerge
    ret_val = subprocess.call(call_list)
  File "C:\Python38-64\lib\subprocess.py", line 340, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Python38-64\lib\subprocess.py", line 854, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Python38-64\lib\subprocess.py", line 1307, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 206] The filename or extension is too long**

Expected Behavior:
Expected all individual scenes to be exported to Scenes\ directory. Program works correctly when the duration is lowered but not when trying to split longer length media.

Computing Environment:

  • OS: Windows 10
  • Python Version: 3.8.2 64bit
  • OpenCV Version: 4.2.0.34

Workaround
After digging into the WinError 206, I discovered that in Windows a process command line is limited to 32,766 characters. This may be what is causing the errors during the mkv splitting, as the amount of scenes in the list is very large. As a workaround I cut the scene_list into 4 portions and then ran each through the split_video_mkvmerge method.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions