Skip to content

Instantly share code, notes, and snippets.

@mittinatten
Last active October 17, 2019 12:20
Show Gist options
  • Select an option

  • Save mittinatten/846f33d91ef4830dece6a79ad6f06fe6 to your computer and use it in GitHub Desktop.

Select an option

Save mittinatten/846f33d91ef4830dece6a79ad6f06fe6 to your computer and use it in GitHub Desktop.

Revisions

  1. mittinatten revised this gist Oct 17, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion get-qt-location.js
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    // Quite crude, but worked for the one example file I had
    // QuickTime docs https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFPreface/qtffPreface.html#//apple_ref/doc/uid/TP40000939-CH202-TPXREF101
    // QuickTime docs https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFPreface/qtffPreface.html
    const fs = require('fs');

    if (!process.argv[2]) {
  2. mittinatten revised this gist Oct 17, 2019. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions get-qt-location.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    // Quite crude, but worked for the one example file I had
    // QuickTime docs https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFPreface/qtffPreface.html#//apple_ref/doc/uid/TP40000939-CH202-TPXREF101
    const fs = require('fs');

    if (!process.argv[2]) {
  3. mittinatten revised this gist Oct 17, 2019. 1 changed file with 71 additions and 64 deletions.
    135 changes: 71 additions & 64 deletions get-qt-location.js
    Original file line number Diff line number Diff line change
    @@ -2,91 +2,98 @@
    const fs = require('fs');

    if (!process.argv[2]) {
    console.error('Please specify a file name');
    process.exit(1);
    console.error('Please specify a file name');
    process.exit(1);
    }

    const fileName = process.argv[2];

    if (!fileName.match(/\.mov$/i)) {
    console.error("Only works with .mov files");
    process.exit(1);
    console.error('Only works with .mov files');
    process.exit(1);
    }

    const file = fs.readFileSync(fileName);

    function getAtom(file, start) {
    if (start + 8 >= file.length || start < 0) {
    return null;
    }
    const size = file.readInt32BE(start);
    return {
    size,
    type: file.toString('ascii', start + 4, start + 8),
    start
    };
    }

    function readAtom(file, atom) {
    return file.toString('ascii', atom.start + 8, atom.start + 1024);
    if (start + 8 >= file.length || start < 0) {
    return null;
    }
    const size = file.readInt32BE(start);
    return {
    size,
    type: file.toString('ascii', start + 4, start + 8),
    start,
    };
    }

    function readKeys(file, atom) {
    let offset = atom.start + 8 + 4 ; // skip version and flags
    const count = file.readInt32BE(offset);
    offset += 4;
    const result = [];
    for (let i = 0; i < count; ++i) {
    const keySize = file.readInt32BE(offset);
    const namespace = file.toString('ascii', offset + 4, offset + 8);
    const value = file.toString('ascii', offset + 8, offset + keySize);
    offset += keySize;
    result.push(value);
    }
    return result;
    const keys = [];
    let offset = atom.start + 8 + 4; // skip version and flags
    const count = file.readInt32BE(offset);
    offset += 4;

    for (let i = 0; i < count; ++i) {
    const keySize = file.readInt32BE(offset);
    const namespace = file.toString('ascii', offset + 4, offset + 8);
    const value = file.toString('ascii', offset + 8, offset + keySize);
    offset += keySize;
    keys.push(value);
    }

    return keys;
    }

    function readItem(file, atom) {
    if (atom) {
    const value = file.toString('ascii', atom.start + 8, atom.start + atom.size);
    return value.split('+').slice(1,3);
    }
    return [];
    function parseCoords(file, atom) {
    if (atom) {
    const value = file
    .toString('ascii', atom.start + 8, atom.start + atom.size)
    .replace(/\/$/, '');
    const coord = value.split('+').slice(1);
    return { lat: coord[0], long: coord[1], alt: coord[2] };
    }
    return null;
    }

    function getItem(file, atom, index) {
    let offset = atom.start + 8 + 4;
    const count = file.readInt32BE(offset);
    const items = getAtoms(file, offset + 4, 'ilist');
    return readItem(file, items[index]);
    function getCoordsFromILST(file, atom, index) {
    let offset = atom.start + 8 + 4;
    const count = file.readInt32BE(offset);
    const items = getAtoms(file, offset + 4);

    return parseCoords(file, items[index]);
    }

    const coord = [];
    function getAtoms(file, start, prefix = '') {
    let atom;
    let offset = start;
    const atoms = [];
    let keys;
    do {
    atom = getAtom(file, offset);
    atoms.push(atom);
    if (atom) {
    if (atom.type.match(/(moov|meta|trak)/)) {
    getAtoms(file, offset + 8, prefix + ':' + atom.type);
    }
    if (atom.type === 'keys') {
    keys = readKeys(file, atom);
    }
    if (atom.type === 'ilst' && keys) {
    coord.push(getItem(file, atom, keys.indexOf('com.apple.quicktime.location.ISO6709')));
    }
    offset = offset + atom.size;
    }
    } while(atom && atom.size);
    function getAtoms(file, start) {
    let atom;
    let offset = start;
    const atoms = [];
    let keys;
    do {
    atom = getAtom(file, offset);
    if (atom) {
    if (atom.type.match(/(moov|meta|trak)/)) {
    atom.children = getAtoms(file, offset + 8);
    }
    if (atom.type === 'keys') {
    keys = readKeys(file, atom);
    }
    if (atom.type === 'ilst' && keys) {
    coord.push(
    getCoordsFromILST(
    file,
    atom,
    keys.indexOf('com.apple.quicktime.location.ISO6709')
    )
    );
    }
    offset = offset + atom.size;
    atoms.push(atom);
    }
    } while (atom && atom.size);

    return atoms;
    return atoms;
    }

    getAtoms(file, 0);
    console.log(coord);
    console.log(coord);
  4. mittinatten revised this gist Oct 17, 2019. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions get-qt-location.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    // Quite crude, but worked for the one example file I had
    const fs = require('fs');

    if (!process.argv[2]) {
  5. mittinatten revised this gist Oct 17, 2019. No changes.
  6. mittinatten created this gist Oct 17, 2019.
    91 changes: 91 additions & 0 deletions get-qt-location.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    const fs = require('fs');

    if (!process.argv[2]) {
    console.error('Please specify a file name');
    process.exit(1);
    }

    const fileName = process.argv[2];

    if (!fileName.match(/\.mov$/i)) {
    console.error("Only works with .mov files");
    process.exit(1);
    }

    const file = fs.readFileSync(fileName);

    function getAtom(file, start) {
    if (start + 8 >= file.length || start < 0) {
    return null;
    }
    const size = file.readInt32BE(start);
    return {
    size,
    type: file.toString('ascii', start + 4, start + 8),
    start
    };
    }

    function readAtom(file, atom) {
    return file.toString('ascii', atom.start + 8, atom.start + 1024);
    }

    function readKeys(file, atom) {
    let offset = atom.start + 8 + 4 ; // skip version and flags
    const count = file.readInt32BE(offset);
    offset += 4;
    const result = [];
    for (let i = 0; i < count; ++i) {
    const keySize = file.readInt32BE(offset);
    const namespace = file.toString('ascii', offset + 4, offset + 8);
    const value = file.toString('ascii', offset + 8, offset + keySize);
    offset += keySize;
    result.push(value);
    }
    return result;
    }

    function readItem(file, atom) {
    if (atom) {
    const value = file.toString('ascii', atom.start + 8, atom.start + atom.size);
    return value.split('+').slice(1,3);
    }
    return [];
    }

    function getItem(file, atom, index) {
    let offset = atom.start + 8 + 4;
    const count = file.readInt32BE(offset);
    const items = getAtoms(file, offset + 4, 'ilist');

    return readItem(file, items[index]);
    }

    const coord = [];
    function getAtoms(file, start, prefix = '') {
    let atom;
    let offset = start;
    const atoms = [];
    let keys;
    do {
    atom = getAtom(file, offset);
    atoms.push(atom);
    if (atom) {
    if (atom.type.match(/(moov|meta|trak)/)) {
    getAtoms(file, offset + 8, prefix + ':' + atom.type);
    }
    if (atom.type === 'keys') {
    keys = readKeys(file, atom);
    }
    if (atom.type === 'ilst' && keys) {
    coord.push(getItem(file, atom, keys.indexOf('com.apple.quicktime.location.ISO6709')));
    }
    offset = offset + atom.size;
    }
    } while(atom && atom.size);

    return atoms;
    }

    getAtoms(file, 0);
    console.log(coord);