Help us understand the problem. What is going on with this article?

ContorGPSで撮影した動画ファイルからnmeaを取り出す

More than 3 years have passed since last update.

始めに・背景

ContorGPSで撮影した動画ファイルにはnmea形式のGPS情報が埋め込まれていて、通常、それを取り出すにはContor Starytellerを使って動画をインポートする必要があります。

↓動画ファイルに埋め込まれたnmea形式の文字列
動画ファイルに埋め込まれたnmea

ところが、OSをWindows10にアップグレードしたところStarytellerがまともに動かなくなってしまいました。

そこで、仕方がないので動画ファイルからnmeaファイルを取りだすプログラムを作成しました。ニッチ過ぎて需要があるかわかりませんがせっかく作ったのでシェアします。そんなに高機能ではないです。

ソース

NmeaExporter.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PushbackInputStream;

public class NmeaExporter {

    public static void main(String[] args) throws FileNotFoundException, IOException {
        if (args.length == 0) {
            usage();
            System.exit(1);
        }

        try (PushbackInputStream is = new PushbackInputStream(new FileInputStream(args[0]), 256)) {
            export(is);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static void export(PushbackInputStream is) throws IOException {
        while (true) {
            byte[] buf = new byte[6];

            // ファイル終端に達したら終了
            int bytes = is.read(buf);
            if (bytes < buf.length) {
                break;
            }

            // 欲しいデータじゃなければスキップ
            if (!equals(buf, "$GPGGA") && !equals(buf, "$GPRMC")) {
                is.unread(buf, 1, buf.length - 1);
                continue;
            }

            // ここまで来ると欲しいデータなので改行文字(\r\n)まで出力
            System.out.print(new String(buf));
            while (true) {
                buf = new byte[2];
                is.read(buf);
                if (equals(buf, "\r\n")) {
                    break;
                }
                System.out.print((char) buf[0]);
                is.unread(buf, 1, 1);
            }
            System.out.println("");
        }
    }

    private static boolean equals(byte[] buf, String str) {
        if (buf.length != str.length()) {
            return false;
        }

        for (int i = 0; i < buf.length; i++) {
            if ((char) buf[i] != str.charAt(i)) {
                return false;
            }
        }

        return true;
    }

    private static void usage() {
        System.err.println("ファイルパスを渡してください。");
    }

}

使い方

ソースをコンパイルして次のコマンドを実行すると。[出力ファイル]で指定したパスにnmeaが出力されます。

java NmeaExporter [入力ファイル] > [出力ファイル]

解説

やっていることはいたってシンプルです。動画ファイルの中から
$GPGGA$GPRMCといったnmeaの文字列を探して、見つかれば逐次出力しています。

ちなみに、Storytellerが出力するnmeaファイルの中には$GPEMTという謎のレコードが含まれるのですが、動画ファイルの中にそんな文字列は含まれていません。そもそもnmeaの仕様にすらないようなので無視しちゃいました。

一文字一文字探していくので、大きな動画ファイルからnmeaを取り出すには結構時間がかかります。探索アルゴリズムを工夫すれば(BM法とか)もう少し高速化できそうですが、いずれにせよ計算量はlog(n)なので数倍速くなる程度でしょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした