I added a sound file to shotcut and then put in some video clips at specific positions with the blank time tag in the mlt file. I can totally understand what you mean: they are off the grid. No matter which framerate.
Seems like there is a drift that accumulates - even if the blank times have the same distance. Strange.
There is no drift if using the same method that Shotcut uses. Otherwise, Shotcut would not be able to save and reopen projects that are an hour long.
Things to remember:
For blanks, length is pure addition to the virtual playhead. But to generate a length, donāt calculate using time; calculate using frames. Determine the number of frames needed to get the virtual playhead (internally represented in frames) to the next start point, and convert that length to time using literal frame rate.
For clips, out points to the start time of the last frame to be shown. This is different than some tools that have out point to the end time of the last frame, or the start time of the next clip.
The HH:MM:SS.ms notation in MLT is wall clock time, not a derivative of NDF or SMPTE. Use literal frame rate (not rounded) to convert milliseconds to frames, do math on frames, then convert back to milliseconds.
eg. a subtitle plays for 5.032 seconds, in a 30fps video:
In theory, it shoud be 150fps + 0.032 seconds offset (the offset is recorded to push back the next subtitle line)
And the timestamp in .mlt should be 00:00:05.000
But, in an actual .mlt reconized by shotcut, it can be 4.999 instead of 5.000.
So, I tried to work out how the timeline was calculated in shotcut, so I can program my app accordingly.
Then after doing bunch of tests, I find Shotcut sometimes calculate eg 1 frame as 0.033333 second, sometimes as 0.033334,
but definately not 1/30 , nor 0.03333333333333 nor 0.333. (and I am too lazy to research the source code to find out why)
How this matters: because when I carefully mark a time 00:02:22.117, some cases it convert back to 8527 frames, some cases it convert to 8528 frames. I can not find a pattern. (this is not a true example, I made it up to show you my point)
The rest of your points are well known to me. And I do agree with you that using the frame counts to start the project for a good foundation of the ādrift-freeā .mlt generator.
A big LMAO here. This app of mine was a 30 minutes project. (I used the string output, and the .srt handling was from my earlier project, that how I was able to made it quickly). But a day later, users here told me it drifts, I spent 4~5 hours researching/patching, and eventually gave up. I ended up giving it a random offset to mitigate some drifting, and consider it is good enough.
My suggestion: donāt waste your time trying/patching your app, until you get a direct absolute answer why it happens (from reading the source code; or the supreme leader tell us how), your life could get better.
Here is the source code that does conversion from HH:MM:SS.ms to frames and back. It should answer all questions.
All timecodes must be calculated as an offset from zero time (the beginning), not as an addition to the previous point. This is why adding 0.333 doesnāt work, because it doesnāt divide evenly into One, and the remainder would add up and drift over time. So every once in a while, the remainder accumulates enough to cause an increment to 0.333334 and then it settles down again for a bit.
Also be aware that Shotcut calculates fps with at least six digits of precision. Using less precision (like 29.97 instead of 29.970030) will cause drift compared to the timecodes created by Shotcut.
Hereās what iāve done so far to test that quickly:
double d_fps = 25.0; // framerate matters! //TODO: get it from MLT
int i_ClipDurationInFrames = 4; // length of dummy clip in frames
double d_ClipDurationInSeconds = (double) ( i_ClipDurationInFrames / d_fps);
int i_LastPosInFrames = 0; // last position on timeline in frames
int i;
for(i=0;i<m_arrayOfTimestamps.GetCount();i++)
{
struct_timestamps = &(m_arrayOfTimestamps.GetAt(i)); // fetch struct_timestamps from array
double d_ClipStartTimeSeconds = (double) (struct_timestamps->f_start * 1.000); // absolute time to start our clip
int i_ClipStartPosFrames = (int)(d_ClipStartTimeSeconds * d_fps); // absolute frame position to start
int i_BlankDurationInFrames = i_ClipStartPosFrames - i_LastPosInFrames; // calculate blank time from last to start in frames
double d_BlankDurationInSeconds = (double) (i_BlankDurationInFrames / d_fps);
(btw. what is the key to paste code? indent 4 doesnāt look nice)
So my little tool is working fine with adding color clips at the correct position from a label.txt file on a new track. It works very accurate even on projects with over 500 clips and 6 tracks.
Thanks to @Austin for his advice about the threatment of time.
I added a new producer to the mlt and a new playlist using this producer multiple times.
At least i added a new track between
producer=ābackgroundā
and the first playlist.
Works as expected. I can share this tool, if someone has an idea where to upload.
But one thing is interesting: when i do the above modification to the mlt project file, the opacity of .MOV clips in the timeline gets affected. Resulting in my overlay animationsā background is no longer transparent, but solid black.
When i then drag this animation.mov in shotcut from the global playlist to the timeline, the background is transparent again. But existing clips of the same .mov on the timeline remain non-transparent⦠?!
I already checked with a diff the previous .mlt file with my generated one: no extra changes except inserting the described new track with the labels.
Any ideas on this? @KKnBB i think weāve done something very similar. Did you experienced this behaviour?
I remember something similar happened to me, and it ended up that I need to generate a āfull sizedā playlist and producer for every line of the subtitle. But I failed to recall how I fixed it in detail.
Can you attach the .mlt file where transparency isnāt working and indicate which track is turning black? The referenced media files arenāt needed. I have a hunch the problem is in the mix definitions in the tractor.
The two top tracks with .MOV clips are not longer transparent in the ā_out.mltā file. So the subordinate tracks with my video clips are not longer shown as i just see the animation from the .mov and itās black background.
Maybe i screwd things up when manipulating the MLT file.
But as you can see, i just added 3 things:
a producer
a playlist using this producer a few times with blanktimes in between
and a reference to that playlist as a track in the first tractor right between
track producer="background"
and
track producer="playlist0"
Where would be the correct position in the tractor for the new playlist?
As i want to see my video clips on top, i inserted it between the first ābackgroundā track and the next āplaylist0ā which is my first video track.
That was the only way, i could put it UNDER my video clips.
Hello - I am also finding my AntiVirus wonāt let me install it.
Did you get anywherecoding your own converter?
I was also wondering if there was an example mlt file that could be used as a template for this.
If there is, then I would look at a script to merge a text file.
Ha sorry for the late reply. Yes, I compiled the binary myself and the download is fully under my control. It should be clean. Thanks for the submit.
The thing I hate most for some anti-virus is, once I modify a line of code to fix a small bug, and compile it again (making a new .exe binary), some anti-virus will mark it suspicious again. Many anti-viruses now are using a big āwhite listā instead of the old-school āvirus listā, they mark all the āunknownā .exe as dangerous.
This app is exactly what Iāve been looking for to burn in captions in Shotcut. Thank you very much!
Unfortunately, the app requires administrator privileges to run, and that means I cannot use it on my work computer. Is there a way that could be remedied in a future update?