diff --git a/LICENSE b/LICENSE
index 58c0cabfa3967b7afdb598d73c15bf5b58c3eb82..bc67651debd1e0fef3081a674d0cbd9655d6a7c5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -10,4 +10,4 @@ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
\ No newline at end of file
+THIS SOFTWARE.
diff --git a/inc/common/common.h b/inc/common/common.h
index df31e41154d27d2b3824f6790289f0ec5e5f978f..3831a0780de73d7f158de416c8cbec2efe00c101 100644
--- a/inc/common/common.h
+++ b/inc/common/common.h
@@ -4,6 +4,11 @@
 #include <unistd.h>
 #include <stdint.h>
 
+/* May be usefull (gcc, see something else for clang):
+   __FLOAT_WORD_ORDER__
+   __ORDER_LITTLE_ENDIAN__
+   __ORDER_BIG_ENDIAN__ */
+
 #define not_implemented() __not_implemented(__func__,__FILE__,__LINE__)
 extern void __not_implemented(const char *func, char *file, int line);
 
@@ -27,6 +32,10 @@ uint32_t be_uint32_t(const uint8_t bytes[], size_t n);
    Restriction: n <= 8 */
 uint64_t be_uint64_t(const uint8_t bytes[], size_t n);
 
+/* Same as `be_uint64_t` but for Big-endian doubles.
+   Restriction: n <= 8 */
+double be_double_t(const uint8_t bytes[], size_t n);
+
 /* Trim the string `str` of the char `c` from the right and the left.
    The string may not be null terminated.
    Returns a pointer to the the trimmed string
diff --git a/inc/lektor/mkv.h b/inc/lektor/mkv.h
index 692b9f7d312bbbfecf82f7e122ae58c5d0f4b412..c2d4efd074ca09032a1b235a8f59b1ab90d536a1 100644
--- a/inc/lektor/mkv.h
+++ b/inc/lektor/mkv.h
@@ -49,7 +49,7 @@ int kara_metadata_read(struct kara_metadata *dst, const char *filename);
 
 /* Reads the duration of the .mkv file `filename`. Returns 0 on success
    and -1 on error. */
-int kara_read_length(size_t *len, const char *filename);
+int kara_read_length(double *len, const char *filename);
 
 /* Write metadata to a mkv file. Returns 0 on success and -1 on error */
 int kara_metadata_write(struct kara_metadata *mdt, const char *filename, const char *mkvpropedit);
diff --git a/src/common.c b/src/common.c
index bb330464876adaa5e3129c024891f2734482178b..705f096d06d28e13a5fe1b0dd5789cf65d53e4ca 100644
--- a/src/common.c
+++ b/src/common.c
@@ -33,6 +33,19 @@ be_uint32_t(const uint8_t bytes[], size_t n)
     return res;
 }
 
+double
+be_double_t(const uint8_t bytes[], size_t n)
+{
+    union {
+        uint8_t _bytes[8];
+        double _double;
+    } res;
+    for (size_t i = 0; i < n; ++i) {
+        res._bytes[i] = bytes[i];
+    }
+    return res._double;
+}
+
 uint64_t
 be_uint64_t(const uint8_t bytes[], size_t n)
 {
diff --git a/src/main/debug.c b/src/main/debug.c
index 88680a3fa26a468655c4af29f857181fbf1669e6..2798d28111bc9fe7fcbc27c0859a1f1b2cbc5dc0 100644
--- a/src/main/debug.c
+++ b/src/main/debug.c
@@ -4,7 +4,7 @@
 int
 main(int argc, char **argv)
 {
-    size_t len = 0;
+    double len = 0;
 
     if (argc != 2)
         return 1;
@@ -12,6 +12,6 @@ main(int argc, char **argv)
     if (kara_read_length(&len, argv[1]) < 0)
         return 2;
 
-    printf("Kara length: %ld\n", len);
+    printf("Kara length: %f\n", len);
     return 0;
 }
diff --git a/src/mkv/mkv.c b/src/mkv/mkv.c
index 7f0c9e2ec49f9703dc6534df4db62a7f9343c6bd..da4c86c58ea1a5b7b30515c60ae5ce857aeab6c4 100644
--- a/src/mkv/mkv.c
+++ b/src/mkv/mkv.c
@@ -131,6 +131,31 @@ mkv_read_uint(struct bufferfd *bf, uint64_t *res)
     return n + (ssize_t) data_len;
 }
 
+/* From https://www.matroska.org/technical/specs/index.html:
+   Float - Big-endian, defined for 4 and 8 octets (32, 64 bits).
+   Here we always return a double. */
+static ssize_t
+mkv_read_float(struct bufferfd *bf, double *res)
+{
+    uint8_t data[8];
+    uint64_t data_len;
+    ssize_t n;
+
+    if ((n = mkv_read_element_length(bf, &data_len)) < 0 || 8 < data_len)
+        return -1;
+
+    if (data_len == 0)
+        *res = 0.;
+    else {
+        if (bufferfd_bytes(bf, data_len, data) < 0)
+            return -1;
+
+        *res = be_double_t(data, data_len);
+    }
+
+    return n + (ssize_t) data_len;
+}
+
 /*
 static ssize_t mkv_read_binary(struct bufferfd * bf, size_t max, uint8_t * res)
 {
@@ -500,11 +525,10 @@ kara_read_tags(struct bufferfd *bf, struct kara_metadata *dst)
 }
 
 static int
-kara_read_segment_info(struct bufferfd *bf, size_t *len)
+kara_read_segment_info(struct bufferfd *bf, double *len)
 {
-    /* TODO: Read correct elements, Duration and TimestampScale,
-       the result will be `*len = Duration * TimestampScale`. */
     uint64_t data_len;
+    uint64_t scale = 1;
 
     if (mkv_read_element_length(bf, &data_len) < 0)
         return -1;
@@ -512,34 +536,34 @@ kara_read_segment_info(struct bufferfd *bf, size_t *len)
     while (data_len > 0) {
         ssize_t n;
         uint32_t eid;
-        uint64_t elen;
 
-        if ((n = mkv_read_element_id(bf, &eid)) < 0) {
+        if ((n = mkv_read_element_id(bf, &eid)) < 0)
             return -1;
-        }
 
         data_len -= n;
 
-        if ((n = mkv_read_element_length(bf, &elen)) < 0)
-            return -1;
-
-        data_len -= (n + elen);
-
-        /* Find what we need */
-
         if (eid == EBML_MKV_SEG_DURATION) {
-            /* HANDLE (TODO) */
-            *len = 1;
+            if ((n = mkv_read_float(bf, len)) < 0)
+                return -1;
+        }
+
+        else if (eid == EBML_MKV_SEG_TS_SCALE) {
+            if ((n = mkv_read_uint(bf, &scale)) < 0)
+                return -1;
         }
 
-        bufferfd_skip(bf, elen);
+        else if ((n = mkv_skip_element(bf)) < 0)
+                return -1;
+
+        data_len -= n;
     }
 
+    *len *= scale;
     return 0;
 }
 
 int
-kara_read_length(size_t *len, const char *filename)
+kara_read_length(double *len, const char *filename)
 {
     errno = 0;
     int status_code = -1;
@@ -562,7 +586,7 @@ kara_read_length(size_t *len, const char *filename)
     if (header_len < 0)
         goto error;
 
-    *len = 0;
+    *len = 0.;
 
     for (;;) {
         if (mkv_read_element_id(&file, &eid) < 0)