Пример #1
0
    def test_parse_emsg(self):
        emsg1 = Box.parse(self.l_emsg1)
        self.assertEqual(emsg1["type"], b'emsg')
        self.assertEqual(emsg1["version"], 0)
        self.assertEqual(emsg1["id"], 811)
        self.assertEqual(emsg1["event_duration"], 233472)
        self.assertEqual(emsg1["scheme_id_uri"], b'urn:scte:scte35:2013:bin')
        self.assertEqual(
            emsg1["message_data"],
            b'\xfc0!\x00\x00\x00\x00\x00\x00\x00\xff\xf0\x10\x05\x00\x00\x03+\x7f\xef\x7f\xfe\x00\x1a\x17\xb0\xc0\x00\x00\x00\x00\x00\xe4a$\x02'
        )

        emsg2 = Box.parse(self.l_emsg2)
        self.assertEqual(emsg2["type"], b'emsg')
        self.assertEqual(emsg2["version"], 0)
        self.assertEqual(emsg2["id"], 812)
        self.assertEqual(emsg2["event_duration"], 233472)
        self.assertEqual(emsg2["scheme_id_uri"], b'urn:scte:scte35:2013:bin')
        self.assertEqual(
            emsg2["message_data"],
            b'\xfc0!\x00\x00\x00\x00\x00\x00\x00\xff\xf0\x10\x05\x00\x00\x03,\x7f\xef\x7f\xfe\x00\x1a\x17\xb0\xc0\x00\x00\x00\x00\x00\xfe\xcc\xb92'
        )

        embe1 = Box.parse(self.l_embe)
        self.assertEqual(embe1["type"], b'embe')
Пример #2
0
 def test_smhd_parse(self):
     in_bytes = b'\x00\x00\x00\x10smhd\x00\x00\x00\x00\x00\x00\x00\x00'
     self.assertEqual(
         Box.parse(in_bytes + b'padding'),
         Container(offset=0)
         (type=b"smhd")(version=0)(flags=0)
         (balance=0)(reserved=0)(end=len(in_bytes))
     )
Пример #3
0
 def test_mdhd_parse(self):
     self.assertEqual(
         Box.parse(
             b'\x00\x00\x00\x20mdhd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0fB@\x00\x00\x00\x00U\xc4\x00\x00'
         ),
         Container(offset=0)(type=b"mdhd")(version=0)(flags=0)(
             creation_time=0)(modification_time=0)(timescale=1000000)(
                 duration=0)(language="und")(end=32))
Пример #4
0
 def test_stsd_parse(self):
     tx3g_data = b'\x00\x00\x00\x00\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x12\xFF\xFF\xFF\xFF\x00\x00\x00\x12ftab\x00\x01\x00\x01\x05Serif'
     in_bytes = b'\x00\x00\x00\x50stsd\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x40tx3g\x00\x00\x00\x00\x00\x00\x00\x01' + tx3g_data
     self.assertEqual(
         Box.parse(in_bytes + b'padding'),
         Container(offset=0)(type=b"stsd")(version=0)(flags=0)(entries=[
             Container(format=b'tx3g')(data_reference_index=1)(
                 data=tx3g_data)
         ])(end=len(in_bytes)))
Пример #5
0
 def test_parse_stsd_urim(self):
     urim_sample_entry = Box.parse(self.l_stsd_emsg1)
     self.assertEqual(len(urim_sample_entry["entries"]), 1)
     for entry in urim_sample_entry["entries"]:
         self.assertEqual(entry["format"], b"urim")
         for l_child in entry["children"]:
             if l_child["type"] != b"uriI":
                 self.assertEqual(l_child["type"][0:3], b'uri')
                 self.assertEqual(l_child["theURI"],
                                  b"urn:mpeg:dash:event:2012")
Пример #6
0
 def test_ftyp_parse(self):
     self.assertEqual(
         Box.parse(b'\x00\x00\x00\x18ftypiso5\x00\x00\x00\x01iso5avc1'),
         Container(offset=0)
         (type=b"ftyp")
         (major_brand=b"iso5")
         (minor_version=1)
         (compatible_brands=[b"iso5", b"avc1"])
         (end=24)
     )
Пример #7
0
 def test_tenc_parse(self):
     self.assertEqual(
         Box.parse(b'\x00\x00\x00 tenc\x00\x00\x00\x00\x00\x00\x01\x083{\x96C!\xb6CU\x9eY>\xcc\xb4l~\xf7'),
         Container(offset=0)
         (type=b"tenc")
         (version=0)
         (flags=0)
         (is_encrypted=1)
         (iv_size=8)
         (key_ID=UUID('337b9643-21b6-4355-9e59-3eccb46c7ef7'))
         (end=32)
     )
Пример #8
0
    def test_parse_trun(self):
        trun_box1 = Box.parse(self.l_trun_emsg)
        self.assertEqual(trun_box1["type"], b'trun')
        self.assertEqual(trun_box1["version"], 0)
        self.assertEqual(
            trun_box1["flags"]["sample_composition_time_offsets_present"],
            False)
        self.assertEqual(trun_box1["flags"]["sample_flags_present"], False)
        self.assertEqual(trun_box1["flags"]["sample_size_present"], True)
        self.assertEqual(trun_box1["flags"]["sample_duration_present"], True)
        self.assertEqual(trun_box1["flags"]["first_sample_flags_present"],
                         False)
        self.assertEqual(trun_box1["flags"]["data_offset_present"], True)
        self.assertEqual(trun_box1["sample_count"], 1)
        self.assertEqual(trun_box1["data_offset"], 112)
        self.assertEqual(len(trun_box1["sample_info"]), 1)
        self.assertEqual(trun_box1["sample_info"][0]["sample_duration"], 25600)
        self.assertEqual(trun_box1["sample_info"][0]["sample_size"], 8)

        trun_box2 = Box.parse(self.l_trun2_emsg)
        self.assertEqual(trun_box2["type"], b'trun')
        self.assertEqual(trun_box2["version"], 0)
        self.assertEqual(
            trun_box2["flags"]["sample_composition_time_offsets_present"],
            False)
        self.assertEqual(trun_box2["flags"]["sample_flags_present"], False)
        self.assertEqual(trun_box2["flags"]["sample_size_present"], True)
        self.assertEqual(trun_box2["flags"]["sample_duration_present"], True)
        self.assertEqual(trun_box2["flags"]["first_sample_flags_present"],
                         False)
        self.assertEqual(trun_box2["flags"]["data_offset_present"], True)
        self.assertEqual(trun_box2["sample_count"], 1)
        self.assertEqual(trun_box2["data_offset"], 112)
        self.assertEqual(len(trun_box2["sample_info"]), 1)
        self.assertEqual(trun_box2["sample_info"][0]["sample_duration"],
                         233472)
        self.assertEqual(trun_box2["sample_info"][0]["sample_size"], 90)
Пример #9
0
    def test_parse_edit_list(self):
        elst_b = Box.parse(
            b'\x00\x00\x00\x1celst\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x0f\xa0\x00\x00\x04\x00\x00\x01\x00\x00'
        )
        [Container(edit_duration=4000)(media_time=1024)]
        self.assertEqual(elst_b["type"], b"elst")
        self.assertEqual(len(elst_b["entries"]), 1)
        self.assertEqual(elst_b["entries"][0]["edit_duration"], 4000)
        self.assertEqual(elst_b["entries"][0]["media_time"], 1024)
        self.assertEqual(elst_b["entries"][0]["media_rate_integer"], 1)
        self.assertEqual(elst_b["entries"][0]["media_rate_fraction"], 0)

        t = dict(
             type=b"elst",
             version=1,
             flags=0,
             entries=[dict(edit_duration=1,media_time=1, media_rate_integer=1, media_rate_fraction=1)\
                 ,dict(edit_duration=2,media_time=2, media_rate_integer=1,
             media_rate_fraction=1)  ],

            )
        elst_b = Box.build(t)
        t2 = Box.parse(elst_b)
        self.assertEqual(len(t["entries"]), len(t2["entries"]))
Пример #10
0
 def test_parse_stbl_progressive(self):
     stbl = Box.parse(l_stbl_audio_4s)
     self.assertNotEqual(stbl, None)
     stsd = BoxUtil.find_and_return_first(stbl, b'stsd')
     self.assertEqual(len(stsd["entries"]), 1)
     self.assertEqual(stsd["entries"][0]["format"], b"mp4a")
     mp4a = stsd["entries"][0]
     self.assertEqual(mp4a["channels"], 2)
     self.assertEqual(mp4a["sampling_rate"], 48000)
     stsz = BoxUtil.find_and_return_first(stbl, b'stsz')
     self.assertNotEqual(stsz, None)
     self.assertEqual(stsz["sample_count"], 189)
     stco = BoxUtil.find_and_return_first(stbl, b'stco')
     self.assertNotEqual(stco, None)
     self.assertEqual(len(stco["entries"]), 1)
     stts = BoxUtil.find_and_return_first(stbl, b'stts')
     self.assertNotEqual(stts, None)
     self.assertEqual(len(stts["entries"]), 2)
Пример #11
0
 def test_udta_terminator_parse(self):
     ilst = b'\x00\x00\x00\x25\xA9\x74\x6F\x6F\x00\x00\x00\x1D\x64\x61\x74\x61\x00\x00\x00\x01\x00\x00\x00\x00\x4C\x61\x76\x66\x35\x37\x2E\x32\x35\x2E\x31\x30\x30'
     input_bytes = (
         b'\x00\x00\x00\x66udta'
         b'\x00\x00\x00\x5ameta\x00\x00\x00\x00'
         b'\x00\x00\x00\x21hdlr\x00\x00\x00\x00\x00\x00\x00\x00mdir\x61\x70\x70\x6C\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         b'\x00\x00\x00\x2Dilst' + ilst + b'\x00\x00\x00\x00')
     self.assertEqual(
         Box.parse(input_bytes),
         Container(offset=0)(type=b'udta')(children=[
             Container(offset=8)(type=b'meta')(version=0)(flags=0)(
                 children=[
                     Container(offset=20)(type=b'hdlr')(version=0)(flags=0)(
                         handler_type=b'mdir')(name=u'')(end=53),
                     Container(offset=53)(type=b'ilst')(data=ilst)(
                         end=len(input_bytes) - 4)
                 ])(end=len(input_bytes) - 4)
         ])(end=len(input_bytes)))
Пример #12
0
    def test_build_emib(self):
        emib_b = Box.build(
            dict(type=b"emib",
                 version=0,
                 reserved=1,
                 presentation_time_delta=-1000,
                 value=b'',
                 id=1,
                 scheme_id_uri=b"my_test_scheme",
                 duration=2000,
                 message_data=b"asdfdasgfaghhgsdgh"))

        emib_b_p = Box.parse(emib_b)
        self.assertEqual(emib_b_p["type"], b'emib')
        self.assertEqual(emib_b_p["presentation_time_delta"], -1000)
        self.assertEqual(emib_b_p["value"], b'')
        self.assertEqual(emib_b_p["id"], 1)
        self.assertEqual(emib_b_p["scheme_id_uri"], b"my_test_scheme")
        self.assertEqual(emib_b_p["duration"], 2000)
        self.assertEqual(emib_b_p["reserved"], 1)
        self.assertEqual(emib_b_p["message_data"], b"asdfdasgfaghhgsdgh")
Пример #13
0
    def test_build_emsg(self):
        emsg_b = Box.build(
            dict(type=b"emsg",
                 version=1,
                 presentation_time=1000,
                 value=b'',
                 id=1,
                 scheme_id_uri=b"my_test_scheme",
                 event_duration=20,
                 timescale=1,
                 message_data=b"asdfdasgfaghhgsdgh"))

        emsg_b_p = Box.parse(emsg_b)
        self.assertEqual(emsg_b_p["type"], b'emsg')
        self.assertEqual(emsg_b_p["version"], 1)
        self.assertEqual(emsg_b_p["presentation_time"], 1000)
        self.assertEqual(emsg_b_p["value"], b'')
        self.assertEqual(emsg_b_p["id"], 1)
        self.assertEqual(emsg_b_p["scheme_id_uri"], b"my_test_scheme")
        self.assertEqual(emsg_b_p["event_duration"], 20)
        self.assertEqual(emsg_b_p["timescale"], 1)
        self.assertEqual(emsg_b_p["message_data"], b"asdfdasgfaghhgsdgh")
Пример #14
0
def get_points_from_bv(path, use_nmea_stream_timestamp=False):
    points = []

    fd = open(path, 'rb')

    fd.seek(0, io.SEEK_END)
    eof = fd.tell()
    fd.seek(0)
    date = None

    first_gps_date = None
    first_gps_time = None
    found_first_gps_date = False
    found_first_gps_time = False

    while fd.tell() < eof:
        try:
            box = Box.parse_stream(fd)
        except RangeError:
            print('error parsing blackvue GPS information, exiting')
            sys.exit(1)
        except ConstError:
            print('error parsing blackvue GPS information, exiting')
            sys.exit(1)

        if box.type.decode('utf-8') == 'free':
            length = len(box.data)
            offset = 0
            while offset < length:
                newb = Box.parse(box.data[offset:])
                if newb.type.decode('utf-8') == 'gps':
                    lines = newb.data

                    # Parse GPS trace
                    for l in lines.splitlines():
                        m = l.lstrip('[]0123456789')
                        # this utc millisecond timestamp seems to be the camera's
                        # todo: unused?
                        # match = re.search('\[([0-9]+)\]', l)
                        # if match:
                        #     utcdate = match.group(1)

                        #By default, use camera timestamp. Only use GPS Timestamp if camera was not set up correctly and date/time is wrong
                        if use_nmea_stream_timestamp == False:
                            if "$GPGGA" in m:
                                match = re.search('\[([0-9]+)\]', l)
                                if match:
                                    epoch_in_local_time = match.group(1)

                                camera_date = datetime.datetime.utcfromtimestamp(
                                    int(epoch_in_local_time) / 1000.0)
                                data = pynmea2.parse(m)
                                if (data.is_valid):
                                    if found_first_gps_time == False:
                                        first_gps_time = data.timestamp
                                        found_first_gps_time = True
                                    lat, lon, alt = data.latitude, data.longitude, data.altitude
                                    points.append((camera_date, lat, lon, alt))

                        if use_nmea_stream_timestamp == True or found_first_gps_date == False:
                            if "GPRMC" in m:
                                try:
                                    data = pynmea2.parse(m)
                                    if data.is_valid:
                                        date = data.datetime.date()
                                        if found_first_gps_date == False:
                                            first_gps_date = date
                                except pynmea2.ChecksumError as e:
                                    # There are often Checksum errors in the GPS stream, better not to show errors to user
                                    pass
                                except Exception as e:
                                    print(
                                        "Warning: Error in parsing gps trace to extract date information, nmea parsing failed"
                                    )
                        if use_nmea_stream_timestamp == True:
                            if "$GPGGA" in m:
                                try:
                                    data = pynmea2.parse(m)
                                    if (data.is_valid):
                                        lat, lon, alt = data.latitude, data.longitude, data.altitude
                                        if not date:
                                            timestamp = data.timestamp
                                        else:
                                            timestamp = datetime.datetime.combine(
                                                date, data.timestamp)
                                        points.append(
                                            (timestamp, lat, lon, alt))

                                except Exception as e:
                                    print(
                                        "Error in parsing gps trace to extract time and gps information, nmea parsing failed due to {}"
                                        .format(e))

                    #If there are no points after parsing just return empty vector
                    if points == []:
                        return []
                    #After parsing all points, fix timedate issues
                    if use_nmea_stream_timestamp == False:
                        # If we use the camera timestamp, we need to get the timezone offset, since Mapillary backend expects UTC timestamps
                        first_gps_timestamp = datetime.datetime.combine(
                            first_gps_date, first_gps_time)
                        delta_t = points[0][0] - first_gps_timestamp
                        if delta_t.days > 0:
                            hours_diff_to_utc = round(delta_t.total_seconds() /
                                                      3600)
                        else:
                            hours_diff_to_utc = round(
                                delta_t.total_seconds() / 3600) * -1
                        utc_points = []
                        for idx, point in enumerate(points):
                            delay_compensation = datetime.timedelta(
                                seconds=-1.8
                            )  #Compensate for solution age when location gets timestamped by camera clock. Value is empirical from various cameras/recordings
                            new_timestamp = points[idx][0] + datetime.timedelta(
                                hours=hours_diff_to_utc) + delay_compensation
                            lat = points[idx][1]
                            lon = points[idx][2]
                            alt = points[idx][3]
                            utc_points.append((new_timestamp, lat, lon, alt))

                        points = utc_points
                        points.sort()

                    else:
                        #add date to points that don't have it yet, because GPRMC message came later
                        utc_points = []
                        for idx, point in enumerate(points):
                            if type(points[idx][0]) != type(
                                    datetime.datetime.today()):
                                timestamp = datetime.datetime.combine(
                                    first_gps_date, points[idx][0])
                            else:
                                timestamp = points[idx][0]
                            lat = points[idx][1]
                            lon = points[idx][2]
                            alt = points[idx][3]
                            utc_points.append((timestamp, lat, lon, alt))

                        points = utc_points
                        points.sort()

                offset += newb.end

            break

    return points
Пример #15
0
def get_points_from_bv(path,use_nmea_stream_timestamp=False):
    points = []
    with open(path, 'rb') as fd:

        fd.seek(0, io.SEEK_END)
        eof = fd.tell()
        fd.seek(0)
        date = None

        first_gps_date = None
        first_gps_time = None
        found_first_gps_date = False
        found_first_gps_time = False

        while fd.tell() < eof:
            try:
                box = Box.parse_stream(fd)
            except RangeError:
                print('error parsing blackvue GPS information, exiting')
                sys.exit(1)
            except ConstError:
                print('error parsing blackvue GPS information, exiting')
                sys.exit(1)

            if box.type.decode('utf-8') == 'free':
                length = len(box.data)
                offset = 0
                while offset < length:
                    newb = Box.parse(box.data[offset:])
                    if newb.type.decode('utf-8') == 'gps':
                        lines = newb.data

                        # Parse GPS trace
                        for l in lines.splitlines():
                            m = l.lstrip('[]0123456789')
                            # this utc millisecond timestamp seems to be the camera's
                            # todo: unused?
                            # match = re.search('\[([0-9]+)\]', l)
                            # if match:
                            #     utcdate = match.group(1)
                            
                            #By default, use camera timestamp. Only use GPS Timestamp if camera was not set up correctly and date/time is wrong
                            if use_nmea_stream_timestamp==False:
                                if "$GPGGA" in m:
                                    match = re.search('\[([0-9]+)\]', l)
                                    if match:
                                        epoch_in_local_time = match.group(1)

                                    camera_date=datetime.datetime.utcfromtimestamp(int(epoch_in_local_time)/1000.0)
                                    data = pynmea2.parse(m)
                                    if(data.is_valid):
                                        if  found_first_gps_time == False:
                                            first_gps_time = data.timestamp
                                            found_first_gps_time = True
                                        lat, lon, alt = data.latitude, data.longitude, data.altitude
                                        points.append((camera_date, lat, lon, alt))

                            if use_nmea_stream_timestamp==True or found_first_gps_date==False:
                                if "GPRMC" in m:
                                    try:
                                        data = pynmea2.parse(m)
                                        if data.is_valid:
                                            date = data.datetime.date()
                                            if found_first_gps_date == False:
                                                first_gps_date=date
                                    except pynmea2.ChecksumError as e:
                                        # There are often Checksum errors in the GPS stream, better not to show errors to user
                                        pass
                                    except Exception as e:
                                        print(
                                            "Warning: Error in parsing gps trace to extract date information, nmea parsing failed")
                            if use_nmea_stream_timestamp==True:
                                if "$GPGGA" in m:
                                    try:
                                        data = pynmea2.parse(m)
                                        if(data.is_valid):
                                            lat, lon, alt = data.latitude, data.longitude, data.altitude
                                            if not date:
                                                timestamp = data.timestamp
                                            else:
                                                timestamp = datetime.datetime.combine(
                                                date, data.timestamp)
                                            points.append((timestamp, lat, lon, alt))

                                    except Exception as e:
                                        print(
                                            "Error in parsing gps trace to extract time and gps information, nmea parsing failed due to {}".format(e))
                        
                        #If there are no points after parsing just return empty vector
                        if points == []:
                            return []
                        #After parsing all points, fix timedate issues
                        if use_nmea_stream_timestamp==False:
                            # If we use the camera timestamp, we need to get the timezone offset, since Mapillary backend expects UTC timestamps
                            first_gps_timestamp = datetime.datetime.combine(first_gps_date, first_gps_time)
                            delta_t = points[0][0]-first_gps_timestamp
                            if delta_t.days>0:
                                hours_diff_to_utc = round(delta_t.total_seconds()/3600)
                            else:
                                hours_diff_to_utc = round(delta_t.total_seconds()/3600) * -1
                            utc_points=[]
                            for idx, point in enumerate(points):
                                delay_compensation = datetime.timedelta(seconds=-1.8) #Compensate for solution age when location gets timestamped by camera clock. Value is empirical from various cameras/recordings
                                new_timestamp = points[idx][0]+datetime.timedelta(hours=hours_diff_to_utc)+delay_compensation
                                lat = points[idx][1]
                                lon = points[idx][2]
                                alt = points[idx][3]
                                utc_points.append((new_timestamp, lat, lon, alt))

                            points = utc_points
                            points.sort()

                        else:
                            #add date to points that don't have it yet, because GPRMC message came later 
                            utc_points=[]
                            for idx, point in enumerate(points):
                                if type(points[idx][0]) != type(datetime.datetime.today()):
                                    timestamp = datetime.datetime.combine(
                                            first_gps_date, points[idx][0])
                                else:
                                    timestamp = points[idx][0]                                    
                                lat = points[idx][1]
                                lon = points[idx][2]
                                alt = points[idx][3]
                                utc_points.append((timestamp, lat, lon, alt))

                            points = utc_points
                            points.sort()

                    offset += newb.end

                break

        return points
Пример #16
0
    def test_parse_stbl_parse_samples_progressive(self):

        moov_a = Box.parse(l_movie_box_audio)
        res = BoxUtil.find_samples_progressive(moov_a, moov_a)

        self.assertEqual(len(res), 189)
Пример #17
0
def get_points_from_bv(path):
    points = []

    fd = open(path, 'rb')

    fd.seek(0, io.SEEK_END)
    eof = fd.tell()
    fd.seek(0)
    date = None
    while fd.tell() < eof:
        try:
            box = Box.parse_stream(fd)
        except RangeError:
            print('error parsing blackvue GPS information, exiting')
            sys.exit(1)
        except ConstError:
            print('error parsing blackvue GPS information, exiting')
            sys.exit(1)

        if box.type.decode('utf-8') == 'free':
            length = len(box.data)
            offset = 0
            while offset < length:
                newb = Box.parse(box.data[offset:])
                if newb.type.decode('utf-8') == 'gps':
                    lines = newb.data

                    for l in lines:
                        if "GPRMC" in l:
                            m = l.lstrip('[]0123456789')
                            try:
                                data = pynmea2.parse(m)
                                date = data.datetime.date()
                            except Exception as e:
                                print(
                                    "Error in extracting the gps trace, nmea parsing failed due to {}"
                                    .format(e))
                            break

                    # Parse GPS trace
                    for l in lines.splitlines():
                        # this utc millisecond timestamp seems to be the camera's
                        # todo: unused?
                        # match = re.search('\[([0-9]+)\]', l)
                        # if match:
                        #     utcdate = match.group(1)

                        m = l.lstrip('[]0123456789')

                        if "GPRMC" in m:
                            try:
                                data = pynmea2.parse(m)
                                date = data.datetime.date()
                            except Exception as e:
                                print(
                                    "Error in parsing gps trace to extract date information, nmea parsing failed due to {}"
                                    .format(e))
                        if "$GPGGA" in m:
                            try:
                                if not date:
                                    print(
                                        "Error, could not extract date from the video gps trace, exiting..."
                                    )
                                    sys.exit(1)
                                data = pynmea2.parse(m)
                                timestamp = datetime.datetime.combine(
                                    date, data.timestamp)
                                lat, lon, alt = data.latitude, data.longitude, data.altitude
                                points.append((timestamp, lat, lon, alt))
                            except Exception as e:
                                print(
                                    "Error in parsing gps trace to extract time and gps information, nmea parsing failed due to {}"
                                    .format(e))

                    points.sort()
                offset += newb.end

            break

    return points
Пример #18
0
def detect_file_type(input_file):
    device = "X"
    make = "unknown"
    model = "unknown"
    if input_file.lower().endswith(".ts"):
        with open(input_file, "rb") as f:
            device = "A"
            input_packet = f.read(188)  #First packet, try to autodetect
            if bytes("\xB0\x0D\x30\x34\xC3", encoding="raw_unicode_escape"
                     ) in input_packet[4:20] or args.device_override == "V":
                device = "V"
                make = "Viofo"
                model = "A119 V3"

            if bytes("\x40\x1F\x4E\x54\x39", encoding="raw_unicode_escape"
                     ) in input_packet[4:20] or args.device_override == "B":
                device = "B"
                make = "Blueskysea"
                model = "B4K"

            while device == "A":
                currentdata = {}
                input_packet = f.read(188)
                if not input_packet:
                    break

                #Autodetect camera type
                if device == 'A' and input_packet.startswith(
                        bytes("\x47\x03\x00", encoding="raw_unicode_escape")):
                    bs = list(input_packet)
                    active = chr(bs[156])
                    lathem = chr(bs[157])
                    lonhem = chr(bs[158])
                    if lathem in "NS" and lonhem in "EW":
                        device = "B"
                        make = "Blueskysea"
                        model = "B4K"
                        print("Autodetected as Blueskysea B4K")
                        break

                if device == 'A' and input_packet.startswith(
                        bytes("\x47\x43\x00", encoding="raw_unicode_escape")):
                    bs = list(input_packet)
                    active = chr(bs[34])
                    lathem = chr(bs[35])
                    lonhem = chr(bs[36])
                    if lathem in "NS" and lonhem in "EW":
                        device = "V"
                        print("Autodetected as Viofo A119 V3")
                        make = "Viofo"
                        model = "A119 V3"
                        break
    if input_file.lower().endswith(
            ".mp4"):  #Guess which MP4 method is used: Novatek, Subtitle, NMEA
        with open(input_file, "rb") as fx:

            if True:
                fx.seek(0, io.SEEK_END)
                eof = fx.tell()
                fx.seek(0)
                lines = []
                while fx.tell() < eof:
                    try:
                        box = Box.parse_stream(fx)
                    except:
                        pass
                    #print (box.type.decode("utf-8"))
                    if box.type.decode("utf-8") == "free":
                        length = len(box.data)
                        offset = 0
                        while offset < length:
                            inp = Box.parse(box.data[offset:])
                            #print (inp.type.decode("utf-8"))
                            if inp.type.decode("utf-8") == "gps":  #NMEA-based
                                lines = inp.data
                                for line in lines.splitlines():
                                    m = str(line).lstrip("[]0123456789")
                                    if "$GPGGA" in m:
                                        device = "N"
                                        make = "NMEA-based video"
                                        model = "unknown"
                                        break
                            offset += inp.end
                    if box.type.decode(
                            "utf-8") == "gps":  #has Novatek-specific stuff
                        fx.seek(0)
                        largeelem = fx.read()
                        startbytes = [
                            m.start()
                            for m in re.finditer(b'freeGPS', largeelem)
                        ]
                        del largeelem
                        if len(startbytes) > 0:
                            make = "Novatek"
                            model = "MP4"
                            device = "T"
                            break

                    if box.type.decode("utf-8") == "moov":
                        try:
                            length = len(box.data)
                        except:
                            length = 0
                        offset = 0
                        while offset < length:
                            inp = Box.parse(box.data[offset:])
                            #print (inp.type.decode("utf-8"))
                            if inp.type.decode("utf-8") == "gps":  #NMEA-based
                                lines = inp.data
                                print(len(inp.data))
                                for line in lines.splitlines():
                                    m = str(line).lstrip("[]0123456789")
                                    if "$GPGGA" in m:
                                        device = "N"
                                        make = "NMEA-based video"
                                        model = "unknown"
                                        #break
                            offset += inp.end
            else:
                pass
            if device == "X":
                fx.seek(0)
                largeelem = fx.read()
                startbytes = [
                    m.start() for m in re.finditer(
                        b'\x00\x14\x50\x4E\x44\x4D\x00\x00\x00\x00', largeelem)
                ]
                del largeelem
                if len(startbytes) > 0:
                    make = "Garmin"
                    model = "unknown"
                    device = "G"
            if device == "X":
                fx.seek(0)
                largeelem = fx.read()
                startbytes = [
                    m.start() for m in re.finditer(b'GPGGA', largeelem)
                ]

                del largeelem
                if len(startbytes) > 0:
                    make = "NEXTBASE"
                    model = "unknown"
                    device = "NB"
    return device, make, model
    def read(self) -> Telemetry:
        tel = Telemetry()
        with open(self.source, 'rb') as fd:

            fd.seek(0, io.SEEK_END)
            eof = fd.tell()
            fd.seek(0)

            while fd.tell() < eof:
                try:
                    box = Box.parse_stream(fd)
                except RangeError:
                    print('error parsing blackvue GPS information, exiting')
                    sys.exit(1)
                except ConstError:
                    print('error parsing blackvue GPS information, exiting')
                    sys.exit(1)

                if box.type.decode('utf-8') == 'free':
                    length = len(box.data)
                    offset = 0
                    while offset < length:
                        newb = Box.parse(box.data[offset:])
                        if newb.type.decode('utf-8') == 'gps':
                            lines = newb.data.decode('utf-8')

                            # Parse GPS trace
                            timestamp = None
                            packet = None
                            for l in lines.splitlines():
                                m = l.lstrip('[]0123456789')
                                if not m:
                                    continue

                                match = re.search('\[([0-9]+)\]', l)
                                # If new timestamp found
                                if match and match.group(1) != timestamp:
                                    if packet:
                                        tel.append(packet)
                                    packet = Packet()
                                    timestamp = match.group(1)
                                    packet[TimestampElement.
                                           name] = TimestampElement(
                                               float(timestamp) * 1e-3)

                                #remove timestamp on tail if it exists
                                try:
                                    m = m[:m.rindex('[')]
                                except:
                                    pass

                                try:
                                    m = m[:m.index("\x00")]
                                except:
                                    pass

                                try:
                                    nmea_data = pynmea2.parse(m)
                                    if nmea_data and nmea_data.sentence_type == 'GGA':
                                        packet[LatitudeElement.
                                               name] = LatitudeElement(
                                                   nmea_data.latitude)
                                        packet[LongitudeElement.
                                               name] = LongitudeElement(
                                                   nmea_data.longitude)
                                        if nmea_data.altitude:
                                            packet[AltitudeElement.
                                                   name] = AltitudeElement(
                                                       nmea_data.altitude)
                                    if nmea_data and nmea_data.sentence_type == 'VTG':
                                        packet[
                                            SpeedElement.name] = SpeedElement(
                                                nmea_data.spd_over_grnd_kmph /
                                                3.6)  #convert to m/s
                                except:
                                    self.logger.warn(
                                        "Couldn't parse nmea sentence. Skipping..."
                                    )

                            if packet:
                                tel.append(packet)
                        offset += newb.end
                    break

            return tel
def get_points_from_bv(path,use_nmea_stream_timestamp=False):
    points = []

    fd = open(path, 'rb')

    fd.seek(0, io.SEEK_END)
    eof = fd.tell()
    fd.seek(0)
    date = None
    while fd.tell() < eof:
        try:
            box = Box.parse_stream(fd)
        except RangeError:
            print('error parsing blackvue GPS information, exiting')
            sys.exit(1)
        except ConstError:
            print('error parsing blackvue GPS information, exiting')
            sys.exit(1)

        if box.type.decode('utf-8') == 'free':
            length = len(box.data)
            offset = 0
            while offset < length:
                newb = Box.parse(box.data[offset:])
                if newb.type.decode('utf-8') == 'gps':
                    lines = newb.data

                    # Parse GPS trace
                    for l in lines.splitlines():
                        # this utc millisecond timestamp seems to be the camera's
                        # todo: unused?
                        # match = re.search('\[([0-9]+)\]', l)
                        # if match:
                        #     utcdate = match.group(1)

                        #By default, use camera timestamp. Only use GPS Timestamp if camera was not set up correctly and date/time is wrong
                        if use_nmea_stream_timestamp==False:
                            m = l.lstrip('[]0123456789')
                            if "$GPGGA" in m:
                                match = re.search('\[([0-9]+)\]', l)
                                if match:
                                    utcdate = match.group(1)

                                date=datetime.datetime.utcfromtimestamp(int(utcdate)/1000.0)
                                data = pynmea2.parse(m)
                                if(data.is_valid):
                                    lat, lon, alt = data.latitude, data.longitude, data.altitude
                                    points.append((date, lat, lon, alt))

                        else:
                            if "GPRMC" in m:
                                try:
                                    data = pynmea2.parse(m)
                                    date = data.datetime.date()
                                except Exception as e:
                                    print(
                                        "Error in parsing gps trace to extract date information, nmea parsing failed due to {}".format(e))
                            
                            if "$GPGGA" in m:
                                try:
                                    if not date:
                                        #discarding Lat/Lon messages if date has not been set yet. TODO: we could save the messages and add the date later
                                        continue 
                                    data = pynmea2.parse(m)
                                    if(data.is_valid):
                                        timestamp = datetime.datetime.combine(
                                            date, data.timestamp)
                                        lat, lon, alt = data.latitude, data.longitude, data.altitude
                                        points.append((timestamp, lat, lon, alt))
                                except Exception as e:
                                    print(
                                        "Error in parsing gps trace to extract time and gps information, nmea parsing failed due to {}".format(e))

                    points.sort()
                offset += newb.end

            break

    return points
Пример #21
0
def get_gps_data_nmea(input_file, device):
    packetno = 0
    locdata = {}
    with open(input_file, "rb") as fx:
        if True:
            fx.seek(0, io.SEEK_END)
            eof = fx.tell()
            fx.seek(0)
            prevts = 0
            lines = []
            while fx.tell() < eof:
                try:
                    box = Box.parse_stream(fx)
                except:
                    pass
                if box.type.decode("utf-8") == "free":
                    try:
                        length = len(box.data)
                    except:
                        length = 0
                    offset = 0
                    while offset < length:
                        inp = Box.parse(box.data[offset:])
                        #print (inp.type.decode("utf-8"))
                        if inp.type.decode("utf-8") == "gps":  #NMEA-based

                            lines = inp.data

                            for line in lines.splitlines():
                                m = str(line)
                                if "$GPRMC" in m:
                                    currentdata = {}
                                    currentdata["ts"] = int(m[3:13])
                                    #print (m)
                                    try:
                                        currentdata["lat"] = float(
                                            m.split(",")[3][0:2]) + float(
                                                m.split(",")[3][2:]) / 60
                                        currentdata["latR"] = m.split(",")[4]
                                        if currentdata["latR"] == "S":
                                            currentdata[
                                                "lat"] = -currentdata["lat"]

                                        currentdata["lon"] = float(
                                            m.split(",")[5][0:3]) + float(
                                                m.split(",")[5][3:]) / 60
                                        currentdata["lonR"] = m.split(",")[6]
                                        if currentdata["lonR"] == "N":
                                            currentdata[
                                                "lon"] = -currentdata["lon"]
                                    except:
                                        pass
                                    try:
                                        currentdata["bearing"] = float(
                                            m.split(",")[9])
                                        currentdata["speed"] = float(
                                            m.split(",")[8]) * 1.6 / 3.6

                                    except:
                                        currentdata["bearing"] = 0
                                        currentdata["speed"] = 0
                                    active = (m.split(",")[2])
                                    nts = currentdata["ts"]

                                    currentdata["metric"] = 0
                                    currentdata["prevdist"] = 0
                                    try:
                                        currentdata["mx"], currentdata[
                                            "my"] = lonlat_metric(
                                                currentdata["lon"],
                                                currentdata["lat"])
                                    except:
                                        pass

                                    if active == "A" and nts > prevts:
                                        locdata[packetno] = currentdata
                                        prevts = nts
                                        packetno += 1

                                    del currentdata
                        offset += inp.end
    return locdata, packetno