Skip to content

Commit b3d4d6a

Browse files
committed
fix(video): ignore undetermined language flag (0x55c4)
1 parent 30b7070 commit b3d4d6a

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

src/mov.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{
77
use chrono::DateTime;
88
use nom::{bytes::streaming, IResult};
99

10-
use crate::{bbox::to_boxes, values::get_cstr};
10+
use crate::{bbox::to_boxes, values::filter_zero};
1111
#[allow(deprecated)]
1212
use crate::{
1313
bbox::{
@@ -216,10 +216,7 @@ fn convert_video_tags(entries: Vec<(String, EntryValue)>) -> BTreeMap<TrackInfoT
216216
.map(|v| (TrackInfoTag::GpsIso6709, EntryValue::Text(v)))
217217
} else if k == "udta.auth" {
218218
v.as_u8array()
219-
// The first 4 bytes is zero, skip them
220-
.and_then(|d| if d.len() > 4 { Some(&d[4..]) } else { None })
221-
// .map(|v| (TrackInfoTag::Author, EntryValue::U8Array(v.to_owned())))
222-
.and_then(|b| get_cstr(b).ok())
219+
.and_then(parse_udta_auth)
223220
.map(|v| (TrackInfoTag::Author, EntryValue::Text(v)))
224221
} else if k.starts_with("udta.") {
225222
let tag = TryInto::<TrackInfoTag>::try_into(k.as_str()).ok();
@@ -258,6 +255,21 @@ fn parse_udta_gps(data: &[u8]) -> Option<String> {
258255
}
259256
}
260257

258+
const ISO_639_2_UND: [u8; 2] = [0x55, 0xc4];
259+
260+
fn parse_udta_auth(data: &[u8]) -> Option<String> {
261+
// Skip leading zero bytes
262+
let data = filter_zero(data);
263+
264+
// Skip leading language flags.
265+
// Refer to: https://exiftool.org/forum/index.php?topic=11498.0
266+
if data.starts_with(&ISO_639_2_UND) {
267+
String::from_utf8(data.into_iter().skip(2).collect()).ok()
268+
} else {
269+
String::from_utf8(data).ok()
270+
}
271+
}
272+
261273
/// *Deprecated*: Please use [`crate::MediaParser`] instead.
262274
///
263275
/// Analyze the byte stream in the `reader` as a MOV file, attempting to extract

src/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ mod tests {
597597
#[test_case("meta.mp4", DurationMs, 1063_u64.into())]
598598
#[test_case("meta.mp4", GpsIso6709, "+27.2939+112.6932/".into())]
599599
#[test_case("meta.mp4", CreateDate, DateTime::parse_from_str("2024-02-03T07:05:38Z", "%+").unwrap().into())]
600-
#[test_case("udta.auth.mp4", Author, "UÄReplayKitRecording".into(); "udta author")]
600+
#[test_case("udta.auth.mp4", Author, "ReplayKitRecording".into(); "udta author")]
601601
#[test_case("auth.mov", Author, "ReplayKitRecording".into(); "mov author")]
602602
fn parse_track_info(path: &str, tag: TrackInfoTag, v: EntryValue) {
603603
let mut parser = parser();

src/values.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,10 +679,12 @@ pub(crate) fn get_cstr(data: &[u8]) -> std::result::Result<String, FromUtf8Error
679679
}
680680
}
681681

682-
fn filter_zero(data: &[u8]) -> Vec<u8> {
682+
pub(crate) fn filter_zero(data: &[u8]) -> Vec<u8> {
683683
data.iter()
684+
// skip leading zero bytes
685+
.skip_while(|b| **b == 0)
686+
// ignore tailing zero bytes, and all bytes after zero bytes
684687
.take_while(|b| **b != 0)
685-
.filter(|b| **b != 0)
686688
.cloned()
687689
.collect::<Vec<u8>>()
688690
}

0 commit comments

Comments
 (0)