Jekyll2021-11-23T01:13:08+00:00https://liz3.github.io/blog//blog/feed.xmlLiz3 BlogLiz3How do time media over the network or when playing back2021-11-23T00:00:00+00:002021-11-23T00:00:00+00:00https://liz3.github.io/blog//blog/media-timing<p>So you’ve got your discord bot or a library for playing video files but somethings just off? Lag after some time or even directly from the beginning?
Chances are that maybe the timing is off, and to be fair its really hard to get it right. Heres how to solve it.</p>
<h2 id="the-naive-approach">The naive approach</h2>
<p>Timing video/audio cant be hard can it? Turns out its not as straight forward as you might think.</p>
<p>The Naive and also my first attempt was just to, send <em>x</em> amount of data for a time period, measure how long that takes and then <em>sleep</em> for the time that took.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>start = now()
to_send = prepare_data() // some encoder/decoder maybe
send_data(to_send) // send data to a blip frame or some network endpoint.
elapsed = now() - start
if elapsed > 0 do
sleep(data_time_amount - elapsed)
end
</code></pre></div></div>
<p>That seams reasonable right?</p>
<h2 id="the-problem">The Problem</h2>
<p>The issue with that approach is that its <em>relative</em>.
The time passed is suspect to the operating system suspending the process, giving it other priority and other factors.
Which means while the approach is <em>theoretically</em> correct, its not going to work unless there is 0 delay beyond your desired one, which will never happen.</p>
<p>Regarding that its also interesting because you learn about kernel schedulers, when i did this, it was often more a problem on macOS then on gnu/linux because the linux kernel scheduler is a lot more aggressive and resource <em>giving</em> then macOS, macOS will make sure its own services have enough priority to keep certain things like the desktop running smoothly.</p>
<h2 id="the-solution">The solution</h2>
<p>I put <em>relative</em> in the previous section in italic for a reason because in that problem is the solution, we need to time in a <em>absolute</em> approach.
That works because(assuming we know the audio packet/frame or video frame duration) we can calculate the position we <strong>should</strong> reach.</p>
<p>Great how do we do that?</p>
<p>Here the solution in c++ from my project <a href="https://github.com/liz3/tokio">tokio</a> in c++</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <thread>
#include <chrono>
</span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">time_point</span> <span class="n">start_point</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
<span class="kt">size_t</span> <span class="n">elapsed_frames</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">frame_duration</span> <span class="o">=</span> <span class="mf">0.02</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">should_play</span><span class="p">)</span> <span class="p">{</span>
<span class="n">send_data</span><span class="p">();</span>
<span class="n">elapsed_frames</span><span class="o">++</span><span class="p">;</span>
<span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">time_point</span> <span class="n">point_now</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
<span class="n">duration</span><span class="o"><</span><span class="kt">double</span><span class="o">></span> <span class="n">absolute_elapsed</span> <span class="o">=</span> <span class="n">duration_cast</span><span class="o"><</span><span class="n">duration</span><span class="o"><</span><span class="kt">double</span><span class="o">>></span><span class="p">(</span><span class="n">point_now</span> <span class="o">-</span> <span class="n">start_point</span><span class="p">);</span>
<span class="kt">double</span> <span class="n">current_play_head</span> <span class="o">=</span> <span class="n">frame_duration</span> <span class="o">*</span> <span class="n">elapsed_frames</span><span class="p">;</span>
<span class="kt">double</span> <span class="n">to_delay</span> <span class="o">=</span> <span class="n">current_play_head</span> <span class="o">-</span> <span class="n">absolute_elapsed</span><span class="p">.</span><span class="n">count</span><span class="p">();</span>
<span class="k">if</span><span class="p">(</span><span class="n">to_delay</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">this_thread</span><span class="o">::</span><span class="n">sleep_for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">microseconds</span><span class="p">((</span><span class="kt">int</span><span class="p">)</span> <span class="p">(</span><span class="n">to_delay</span> <span class="o">*</span> <span class="mi">1000000</span><span class="p">)));</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>So what do we do here?
First we need to know 2 things:</p>
<ol>
<li>the current time in a high resolution - <code class="language-plaintext highlighter-rouge">start_point</code></li>
<li>how long in absolute time one iteration of our loop passes, here <code class="language-plaintext highlighter-rouge">frame_duration</code> 2% of a second.</li>
</ol>
<p>In the loop we send our data and then increment a simple counter per iteration.</p>
<p>Then we calculate the <strong>absolute</strong> time elapsed since we started playing(<code class="language-plaintext highlighter-rouge">absolute_elapsed</code>), that gets rid of that relative issue from the naive approach.
After that we calculated the <code class="language-plaintext highlighter-rouge">current_play_head</code>, basically where the audio should be after the sleep we are now starting.
Lastly we calculate the actual amount to sleep(<code class="language-plaintext highlighter-rouge">to_delay</code>) by substracting the elapsed time from the play head.</p>
<p>Then if needed we sleep by that amount.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I learned this way of calculating by reading the discord.py source code and how they do it.</p>
<p>I hope you where able to take something from this and maybe even use it!</p>Liz3So you’ve got your discord bot or a library for playing video files but somethings just off? Lag after some time or even directly from the beginning? Chances are that maybe the timing is off, and to be fair its really hard to get it right. Heres how to solve it.How Disney ruined Star Wars2021-08-10T00:00:00+00:002021-08-10T00:00:00+00:00https://liz3.github.io/blog//blog/how-disney-killed-star-wars<p>Im a huge star wars fan, theres no doubt in that, its amazing how the first 6 parts combine science-fiction with spiritual topics and even some deep theming.
Of course its not perfect. Lucasfilm didnt always do everything perfect and its still confusing how they wrote out the Anakin & Padmé to she being what, 18 years older? but thats another topic.</p>
<h2 id="how-the-problem-was-able-to-be-created">How the problem was able to be created</h2>
<p>The first 6 parts where compared to the later parts a lot more serious. Not necasserily really darker, but they definitely had more seriousness to them.
Why is that?</p>
<p>In the first 6 movies the emphasis is strongly on holding to the code of the jedi and following it closely. A good example is the 2 part when Anakin asks the ship to be landed and he gets in an argument with his master kenobi.</p>
<p>Theres also a great focus on the aspect of master/apprentice and the fact you should be thriving to get more closely with the force and become wiser.
That does not mean there cant be fun, in the second and third part how count doku tries to hold his fights very very “english style” being polite is one example.</p>
<p>And lastly while yes of course it was possible to do things which even in the star wars galaxy where crazy there was still a system behind it, disney broke the system a lot of times for no real reasons.</p>
<h2 id="the-problem">The Problem</h2>
<p>Disney!</p>
<p>Disney tried to turn star wars into a bad comedy show half serious in the star wars franchise?</p>
<p>One of my facorite examples is in the 8th film where Snoke tries to recrute kailo and speaks: “a new Vader”, which is just mind boggling. Vader was created because anakin over estimated his skills in a battle with his old master kenobi. Vader was just the name.
I shows how little disney tried to develop the story and how desperately they tried to not let old characters disappear. a good counter example is kenobis master Qui-Gon Jinn, he was one of the main actors in the first part and had one more appearance at the end of the 3 part. but thats it. he character is gone.</p>
<p>Another example that shows how they couldnt let characters go, is how lea saved herself randomly out of space pulling herself back to the ship using the force, yes theres the jedi jump but this would not hve been possible normally, again becasuse they couldnt let a main character die.</p>
<p>Then the scene where rai gives luke anakins light saber and he just throws it away…disney trying to be funny in the wrong way. In a normal star wars he would have maybe also turned down the request to train ray, but not in that way.</p>
<p>I could give endless more examples but i think i made the point.</p>
<h2 id="how-to-solve-the-problem">How to solve the problem</h2>
<p>Bring back the old style to think about the force, manners and the style to write the films.</p>
<p>But most importanly. LET GO OF MAIN CHARCTERS, move the story.
Yes they let Luke, lea and han go but bring back palpatine without explanation?!</p>
<p>And please also film some scenes on coruscant, i miss that place.</p>Liz3Im a huge star wars fan, theres no doubt in that, its amazing how the first 6 parts combine science-fiction with spiritual topics and even some deep theming. Of course its not perfect. Lucasfilm didnt always do everything perfect and its still confusing how they wrote out the Anakin & Padmé to she being what, 18 years older? but thats another topic.