Why do I get a different timecode when using the same value in a variable?

50 views Asked by At

I'm using this script to turn frames into timecode. Why do I get 00:30:00:00 as result when using 43156.8 as value, but 00:29:59:23 when passing the exact same value as a variable?

function framesToTC($frames, $framerate) {
    $hours = floor( $frames / ( $framerate * 60 * 60 ) );
    $framesleft = $frames - ($hours * $framerate * 60 * 60);
    $minutes = floor( $framesleft / ( $framerate * 60 ) );
    $framesleft -= ( $minutes * $framerate * 60 );
    $seconds = floor( $framesleft / ( $framerate ) );
    $framesleft -= ( $seconds * $framerate );
    $tc = sprintf("%02d:%02d:%02d:%02d", $hours, $minutes, $seconds, $framesleft );
    return $tc;
}
$frames = 86400000/48000*23.976; //43156.8
echo framesToTC($frames, 23.976) . '<br />'; //00:29:59:23
echo framesToTC(43156.8, 23.976); //00:30:00:00
1

There are 1 answers

2
ArtisticPhoenix On

I exploded you function (when in doubt print it out, that's my motto)

<?php

function framesToTC($frames, $framerate) {
    echo "\n".str_pad(" START ", 40, "=", STR_PAD_BOTH)."\n";
    echo "frames: {$frames}\n";
    echo "framerate: {$framerate}\n";

    $hours = floor( $frames / ( $framerate * 60 * 60 ) );
    echo "hours: {$hours}\n";

    $framesleft = $frames - ($hours * $framerate * 60 * 60);
    echo "framesleft: {$framesleft}\n";

    $x = $framesleft / ( $framerate * 60 );
    echo "x: {$x}\n";
    echo str_pad(" DEVIATION ", 40, "-", STR_PAD_BOTH)."\n";
    $minutes = floor( $x );
    echo "minute: {$minutes}\n";

    $framesleft -= ( $minutes * $framerate * 60 );
    echo "framesleft: {$framesleft}\n";

    $seconds = floor( $framesleft / ( $framerate ) );
    echo "seconds: {$seconds}\n";

    $framesleft -= ( $seconds * $framerate );
    echo "framesleft: {$framesleft}\n";

    $tc = sprintf("%02d:%02d:%02d:%02d", $hours, $minutes, $seconds, $framesleft );
    echo "tc: {$tc}\n";

    return $tc;
}

$frames = (86400000/48000*23.976); //43156.8
echo framesToTC($frames, 23.976) . "\n"; //00:29:59:23
echo framesToTC(43156.8, 23.976); //00:30:00:00

$frames = (86400000/48000*23.976); //43156.8
echo framesToTC($frames, 23.976) . "\n"; //00:29:59:23
echo framesToTC(43156.8, 23.976); //00:30:00:00

Outputs

================ START =================
frames: 43156.8
framerate: 23.976
hours: 0
framesleft: 43156.8
x: 30
-------------- DEVIATION ---------------
minute: 29
framesleft: 1438.56
seconds: 59
framesleft: 23.975999999998
tc: 00:29:59:23
00:29:59:23

================ START =================
frames: 43156.8
framerate: 23.976
hours: 0
framesleft: 43156.8
x: 30
-------------- DEVIATION ---------------
minute: 30
framesleft: 7.2759576141834E-12
seconds: 0
framesleft: 7.2759576141834E-12
tc: 00:30:00:00
00:30:00:00

See it here. http://sandbox.onlinephpfunctions.com/code/918f5187e5dbab3f03812112a54f6b57754f5e7e

You can "fix" i use the word loosly by rounding the $framesleft before it. Here

echo "framesleft: {$framesleft}\n";

$framesleft = floor($framesleft);

$x = $framesleft / ( $framerate * 60 );

Outputs

================ START =================
frames: 43156.8
framerate: 23.976
hours: 0
framesleft: 43156.8
x: 29.999443888333
-------------- DEVIATION ---------------
minute: 29
framesleft: 1437.76
seconds: 59
framesleft: 23.176000000002
tc: 00:29:59:23
00:29:59:23

================ START =================
frames: 43156.8
framerate: 23.976
hours: 0
framesleft: 43156.8
x: 29.999443888333
-------------- DEVIATION ---------------
minute: 29
framesleft: 1437.76
seconds: 59
framesleft: 23.176000000002
tc: 00:29:59:23
00:29:59:23

Check it out here

http://sandbox.onlinephpfunctions.com/code/c78037e52d97ff50094cbc3b045309d155a302fa

I'm guessing it has something to do with float precision, but that's above my pay grade. But at least that gets rid of the deviation in this case. You may have to use ceil or round I don't know what the correct answer should be. I just poke at stuff tell it works or breaks all the way ... lol