Modify code so each snippets start from begin instead end - linux

source : https://davidwalsh.name/video-preview#comment-515168
the part of code that trim videos into snippets :
# Loop and generate video snippets
mkdir $tempdir
interval=$(($length/$desiredsnippets-$starttimeseconds))
for i in $(seq 1 $desiredsnippets)
do
# Format the second marks into hh:mm:ss format
start=$(($(($i*$interval))+$starttimeseconds))
formattedstart=$(printf "%02d:%02d:%02d\n" $(($start/3600)) $(($start%3600/60)) $(($start%60)))
echo 'Generating preview part ' $i $formattedstart
# Generate the snippet at calculated time
ffmpeg -i $sourcefile -vf scale=$dimensions -preset fast -qmin 1 -qmax 1 -ss $formattedstart -t $snippetlengthinseconds -threads $(nproc) $tempdir/$i.mp4
done
`
Video length is 3600 (60mins)
Desired snippets = 30, that mean 2mins each
It always start at 0:02:00 to 0:04:00 -> and so on
but i want it start at 0:00:00 (1st snippet) -> 0:02:00 (2nd snippet) -> (this put in code because it said invalid code format)
I want to make it trim from start of each snippets instead end of each snippets.
This code trim video into multiple parts(snippets) that set by user, and then merged all snippets into one video.

Related

FFmpeg Concat audio giving extra milliseconds

Am Trying to concat 2 audio, i Want exact duration with millisecond accuracy.
my fist audio : audio1 = 17.2 seconds
my second audio : audio2 = 3.422 seconds
the concated audio should be 20.622 second but when i concat this audio ,
result audio duration is 20.698 second ,
how it's possible.
Concate command :-
ffmpeg -i processing1.m4a -i fileName_0_hi.m4a -filter_complex '[0:a][1:a]concat=n=2:v=0:a=1' output1.m4a
enter image description here
same issue with this command also :-
ffmpeg -f concat -i test.txt -c copy abc.m4a

ffmpeg break up videos with frame persecond

Theres a command to extract images of a video providing frame per seconds
ffmpeg -i "vide.mp4" -vf fps=1 frames/frame_%04d.png -hide_banner
Is there a command in ffmpeg to cut video providing fps and save it as video(.mp4 / avi) file like the command above?
What i currently have is i created a method to cut the videos with start and endtime but i firstly created a method to get the length of a video so that i could cut the video base on how many frames that was generated by the above command.
def get_length(self):
"""
Gets the length of a video in seconds
Returns:
float : Length of the video
"""
print("Getting video length: " + self.video_string_path)
command = 'ffprobe -i "'+self.video_string_path+'" -show_entries format=duration -v quiet -of csv="p=0"'
self.command = command
length = str(cmd.execute(command)).strip()
print("lenght: "+length+" second(s)")
return float(length)
def cut(self, start_time, duration, output_file_name = 'output_file_name.mp4', save_to =''):
"""
Cut a video on a specific start time of the video and duration.
Check ffmpeg documentation https://ffmpeg.org/ffmpeg.html for more information about the parameters
Parameters:
start_time : string
is the value of ffmpeg -ss with the format: 00:00:00.000
duration : string | int | float
is the end point where the video will be cut. Can be the same with start_time format but it could also handle integer as in seconds
output_file_name : string
is the file name once the file is save in the hardisk
save_to : string | optional
is the directory where the file will be saved
Returns:
string: file location of the cutted video
"""
self.make_sure_save_dir_exits(save_to)
print('Cutting ' + self.video_string_path + ' from ' + start_time + ' to ' + str(duration))
print('Please wait...')
file = '"' + self.save_to + output_file_name + '"'
command = 'ffmpeg -i "' + self.video_string_path + '" -ss ' + str(start_time) + ' -t ' + str(duration) + ' -c copy -y ' + file
self.command = command
cmd.execute(command)
file_loc = self.get_save_to_dir() + output_file_name
print('Done: Output file was saved to "' + file_loc + '"')
return file_loc + output_file_name
Use
ffmpeg -ss {start_time} -t {duration} -i "vide.mp4" -vf fps=X -c:a copy out.mp4
where X is your output framerate.
To segment the entire file,
ffmpeg -i "vide.mp4" -vf fps=X
-f segment -segment_time {duration} -force_key_frames expr:gte(t,n_forced*{duration})
-reset_timestamps 1 -segment_time_delta 1.0 -c:a copy out%d.mp4
Another way to break up video into smaller chunks is the following command.
ffmpeg -i somefile.mp3 -f segment -segment_time 3 -c copy out%03d.mp3
https://www.ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment

Is there a command line tool or ffmpeg /sox command to generate speech labels? similar to audacity sound finder

Is there a command line tool or ffmpeg / sox command to generate speech labels? similar to audacity sound finder.
Only timeStart and timeEnd are needed in the output.
Preferably, to generate from a given timeStart to a given timeEnd.
The silencedetect filter will print out a readout of silences. You can pair each silence end with the next silence start to identify speech segments. If the first silence start value is not zero, then the first speech segment is 0 to that value. Else, you can discard it.
To log the filter output to a file, pair it with the metadata filter.
ffmpeg -i out_.mp3 -af "silencedetect=noise=-18dB:d=0.15,ametadata=mode=print:file=vol.txt" -f null -
1- Extract time:
ffmpeg -i input.mp3 -ss 00:00:00 -to 00:10:00 -acodec copy output.mp3
2- Execute silentdetect:
ffmpeg -i output.mp3 -af silencedetect=noise=-18dB:d=0.15 -f null - 2> vol.txt
3- Generate labels with javaScript:
var inp=document.getElementById("inp"), outp=document.getElementById("outp");
var c, st=[], et=[], a=inp.value.split('\n');
for(var i=1; i<a.length; i++){
c=a[i].split(' | ');
(c.length==1?et.push(c[0].split(' ')[4]):st.push(c[0].split(' ')[4]) )
};
var t='';
for (var i=0;i<et.length; i++){
t+=st[i]+'\t'+et[i]+'\t'+(i+1)+'\n'
};
outp.value=t;

How to trim and merge using Fluent FFMpeg?

Here's what I want to do with fluent-ffmpeg:
I have 3 input files. An intro, main, and outro video. I wish to merge the three, while trimming the main video. Here is my code:
var ffmpegCommand = ffmpeg();
ffmpegCommand.addInput(introVideo);
ffmpegCommand.addInput(mainVideo).seekInput(20).duration(3);
ffmpegCommand.addInput(outroVideo);
ffmpegCommand.on('error', function(err, stdout, stderr){
console.log("FAILED!\n\t"+err+"\n\t"+stdout+"\n\t"+stderr);
});
ffmpegCommand.on('end', function(){
console.log('COMPLETE!');
});
ffmpegCommand.on('start', function(commandLine) {
console.log('Spawned Ffmpeg with command: ' + commandLine);
});
ffmpegCommand.mergeToFile('final.mp4', './vid_files/tmp');
The program executes fine, but when I ffplay final.mp4, the result is that introVideo plays then the video appears to freeze. According to the fluent-ffmpeg documentation, it states "Each of these [Input options] methods apply on the last input added". So I can't figure out why that syntax doesn't seem to work...
How can I trim the main video to send to mergeToFile?
Note that this works fine if I don't have .seekinput(20).duration(3) on the second addInput.
Oh, here's the outputted commandLine value:
ffmpeg -i ./vid_files/intro.mp4 -ss 20 -i ./vid_files/main.mp4 -i ./vid_files/outro.mp4 -y -filter_complex concat=n=3:v=1:a=1 -t 3 final.mp4

How can I check the last 5 min overall cpu usage using SAR

I know this example of sar sar -u 1 3 which gives statistics for the next 3 seconds with 1 second interval .
However sar also keeps on collecting the information in background (My cron set to collect stats for every minute ) . Is there any way I can simply query using sar command to tell the last 5 mins statistics and its average .
Right now I am using following below command
interval=5; sar -f /var/log/sysstat/sa22 | tail -n $interval | head -n -1 | awk '{print $4+$6}'| awk '{s+=$1} END {print s/$interval}'
to check the overall cpu usage in last 5 min .
Is there a better way ?
Unfortunately when using the -f option in sar together with interval and count it doesn't return the average value for the given interval (as you would expect). Instead it always returns the first recorded value in the sar file
The only way to work around that is to use the -s option which allows you to specify a time at which to start your sampling period. I've provided a perl script below that finishes with a call to sar that is constructed in a way that will return what you're looking for.
Hope this helps.
Peter Rhodes.
#!/usr/bin/perl
$interval = 300; # seconds.
$epoch = `date +%s`;
$epoch -= $interval;
$time = `date -d \#$epoch +%H:%M:00`;
$dom = `date +%d`;
chomp($time,$dom);
system("sar -f /var/log/sysstat/sa$dom -B -s $time 300 1");

Resources