Hi, I'm working on a project using a QProcess to call a script to segment video files using ffmpeg. The idea is to call within the script the command to segment a video file into many chunks of a few seconds, selected by the user. The script also converts the video file from mkv to mp4, but that does not seem to have any issues. I have tested the script from the command line and it works just fine, however when I call it with a QProcess in my code the video segments have a wrong length (should be 30 seconds but are of less than a second in duration).
The script has as arguments the directory of the video file and the duration of the segments, and is called from within a method like so:
connect(process, &QProcess::readyReadStandardError,
this, &GStreamerManager::readyReadStandardError);
connect(process, &QProcess::readyReadStandardOutput,
this, &GStreamerManager::readyReadStandardOutput);
t.restart();
QLOG_INFO() << "Segmenting video file into mp4 files...";
arguments << video_finfo.absoluteFilePath()
<<
QString::number(_params.
video_split_interval_s);
QLOG_INFO() << arguments;
process->start("mkv2mp4s", arguments);
process->waitForFinished();
QLOG_INFO
() <<
QString("Command %1 exited with code %2") .arg(process->program()).arg(process->exitCode());
QLOG_INFO
() <<
QString("MP4 converted! Delay %1 mseconds").
arg(t.
elapsed());
QProcess *process = new QProcess();
connect(process, &QProcess::readyReadStandardError,
this, &GStreamerManager::readyReadStandardError);
connect(process, &QProcess::readyReadStandardOutput,
this, &GStreamerManager::readyReadStandardOutput);
QTime t;
t.restart();
QLOG_INFO() << "Segmenting video file into mp4 files...";
QStringList arguments;
arguments << video_finfo.absoluteFilePath()
<< QString::number(_params.video_split_interval_s);
QLOG_INFO() << arguments;
process->start("mkv2mp4s", arguments);
process->waitForFinished();
QLOG_INFO() << QString("Command %1 exited with code %2")
.arg(process->program()).arg(process->exitCode());
QLOG_INFO() << QString("MP4 converted! Delay %1 mseconds").arg(t.elapsed());
To copy to clipboard, switch view to plain text mode
The script, mkv2mp4s goes like so:
#!/bin/bash
# Author: Leandro Candau Sánchez de Ybargüen
# Description: Split a mkv to many mp4 videos using ffmpeg
# Exit values: 0: No error | 1: Wrong arguments | 2: ffmpeg not installed | 3: Error mp4 split |
# 4: Error mp4 creation | 5: Error mkv split
function echo_error {
echo $1 1>&2
}
if [ $# -ne 2 ]; then
echo "Usage: $0 <path_to_video> <split_time_s>"
exit 1
fi
if ! command -v ffmpeg > /dev/null; then
echo_error "ffmpeg is not installed. Please install FFmpeg package."
exit 2
fi
input_mkv_path=$1
split_time_s=$2
exit_value=0
video_basename="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)"
output_mp4_path="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv).mp4"
output_mp4_split="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)_%d.mp4"
input_mkv_split="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)_%d.mkv"
echo "Path to mkv: "$input_mkv_path""
echo "Video split seconds: "$split_time_s""
echo "Output mp4: "$output_mp4_path""
echo "Output mp4 split: "$output_mp4_split""
echo "Creating mp4 video $output_mp4_path from mkv $input_mkv_path..."
{
ffmpeg -i $input_mkv_path -codec copy $output_mp4_path
} &> /dev/null
if test -f "$output_mp4_path"; then
echo "New video file "$output_mp4_path" has been created"
echo "Removing old mkv file..."
rm $input_mkv_path
echo "Spliting mp4 file in "$split_time_s" seconds chunks"
{
ffmpeg -i $output_mp4_path -c copy -segment_time $split_time_s -f segment $output_mp4_split
} &> /dev/null
if ls ""$video_basename"_0.mp4" 1> /dev/null 2>&1; then
echo "Removing old mp4 file..."
rm $output_mp4_path
else
echo_error "Split files do not exist!"
exit_value=3
fi
else
echo_error "mp4 creation failed!"
exit_value=4
echo "Spliting mkv file in "$split_time_s" seconds chunks"
{
ffmpeg -i $input_mkv_path -c copy -segment_time $split_time_s -f segment $input_mkv_split
} &> /dev/null
if ls ""$video_basename"_0.mkv" 1> /dev/null 2>&1; then
echo "Removing old mkv file..."
rm $input_mkv_path
else
echo_error "Split mkv files do not exist!"
exit_value=5
fi
fi
# Format the file name from basefile_<0|1|2...>.mp4|mkv to basefile_<offset_seconds>.mp4|mkv
for filename in $(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)_*.m*; do
substring=$(echo $filename | grep -oP "_\d+\.") # substring con el patron _#.
value=$(echo $substring | grep -oP "\d+") # valor de # del string anterior
value=_$(( $value*$split_time_s )). # valor # * split_time_s
new_filename=${filename/$substring/$value}
if [ $new_filename != $filename ]; then # evita warning en el _0 pq se llama igual
mv $filename ${filename/$substring/$value} # el string original reemplazando substring por _value.
fi
done
exit $exit_value
#!/bin/bash
# Author: Leandro Candau Sánchez de Ybargüen
# Description: Split a mkv to many mp4 videos using ffmpeg
# Exit values: 0: No error | 1: Wrong arguments | 2: ffmpeg not installed | 3: Error mp4 split |
# 4: Error mp4 creation | 5: Error mkv split
function echo_error {
echo $1 1>&2
}
if [ $# -ne 2 ]; then
echo "Usage: $0 <path_to_video> <split_time_s>"
exit 1
fi
if ! command -v ffmpeg > /dev/null; then
echo_error "ffmpeg is not installed. Please install FFmpeg package."
exit 2
fi
input_mkv_path=$1
split_time_s=$2
exit_value=0
video_basename="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)"
output_mp4_path="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv).mp4"
output_mp4_split="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)_%d.mp4"
input_mkv_split="$(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)_%d.mkv"
echo "Path to mkv: "$input_mkv_path""
echo "Video split seconds: "$split_time_s""
echo "Output mp4: "$output_mp4_path""
echo "Output mp4 split: "$output_mp4_split""
echo "Creating mp4 video $output_mp4_path from mkv $input_mkv_path..."
{
ffmpeg -i $input_mkv_path -codec copy $output_mp4_path
} &> /dev/null
if test -f "$output_mp4_path"; then
echo "New video file "$output_mp4_path" has been created"
echo "Removing old mkv file..."
rm $input_mkv_path
echo "Spliting mp4 file in "$split_time_s" seconds chunks"
{
ffmpeg -i $output_mp4_path -c copy -segment_time $split_time_s -f segment $output_mp4_split
} &> /dev/null
if ls ""$video_basename"_0.mp4" 1> /dev/null 2>&1; then
echo "Removing old mp4 file..."
rm $output_mp4_path
else
echo_error "Split files do not exist!"
exit_value=3
fi
else
echo_error "mp4 creation failed!"
exit_value=4
echo "Spliting mkv file in "$split_time_s" seconds chunks"
{
ffmpeg -i $input_mkv_path -c copy -segment_time $split_time_s -f segment $input_mkv_split
} &> /dev/null
if ls ""$video_basename"_0.mkv" 1> /dev/null 2>&1; then
echo "Removing old mkv file..."
rm $input_mkv_path
else
echo_error "Split mkv files do not exist!"
exit_value=5
fi
fi
# Format the file name from basefile_<0|1|2...>.mp4|mkv to basefile_<offset_seconds>.mp4|mkv
for filename in $(dirname "$input_mkv_path")/$(basename "$input_mkv_path" .mkv)_*.m*; do
substring=$(echo $filename | grep -oP "_\d+\.") # substring con el patron _#.
value=$(echo $substring | grep -oP "\d+") # valor de # del string anterior
value=_$(( $value*$split_time_s )). # valor # * split_time_s
new_filename=${filename/$substring/$value}
if [ $new_filename != $filename ]; then # evita warning en el _0 pq se llama igual
mv $filename ${filename/$substring/$value} # el string original reemplazando substring por _value.
fi
done
exit $exit_value
To copy to clipboard, switch view to plain text mode
I would appreciate any insight on how to deal with this. Thanks.
Bookmarks