mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
mkvpropedit: add support for the "LanguageIETF" track header element
Using the `language` property will act on both the old language and the new "LanguageIETF" element while using the `language-ietf` property will only work on the new "LanguageIETF" element. Part of the implementation of #2419.
This commit is contained in:
parent
4a1af79ab3
commit
493e27039b
3
NEWS.md
3
NEWS.md
@ -30,6 +30,9 @@
|
||||
the simple chapter format or when generating chapters due to the
|
||||
`--generate-chapters` command line option. Part of the implementation of
|
||||
#2419.
|
||||
* mkvpropedit: IETF BCP 47/RFC 5646 language tags: setting/deleting the track
|
||||
language now acts on both the old language element as well as the
|
||||
"LanguageIETF" track header element. Part of the implementation of #2419.
|
||||
|
||||
## Bug fixes
|
||||
|
||||
|
@ -138,7 +138,8 @@ property_element_c::init_tables() {
|
||||
"If set to 0, the reference pseudo-cache system is not used."));
|
||||
ELE("default-duration", KaxTrackDefaultDuration::ClassInfos, YT("Default duration"), YT("Number of nanoseconds (not scaled) per frame."));
|
||||
ELE("name", KaxTrackName::ClassInfos, YT("Name"), YT("A human-readable track name."));
|
||||
ELE("language", KaxTrackLanguage::ClassInfos, YT("Language"), YT("Specifies the language of the track in the Matroska languages form."));
|
||||
ELE("language", KaxTrackLanguage::ClassInfos, YT("Language"), YT("Specifies the language of the track."));
|
||||
ELE("language-ietf", KaxLanguageIETF::ClassInfos, YT("Language (IETF BCP 47)"), YT("Specifies the language of the track in the form of a BCP 47 language tag."));
|
||||
ELE("codec-id", KaxCodecID::ClassInfos, YT("Codec ID"), YT("An ID corresponding to the codec."));
|
||||
ELE("codec-name", KaxCodecName::ClassInfos, YT("Codec name"), YT("A human-readable string specifying the codec."));
|
||||
ELE("codec-delay", KaxCodecDelay::ClassInfos, YT("Codec-inherent delay"), YT("Delay built into the codec during decoding in ns."));
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <ebml/EbmlUnicodeString.h>
|
||||
#include <matroska/KaxSegment.h>
|
||||
|
||||
#include "common/common_pch.h"
|
||||
#include "common/bcp47.h"
|
||||
#include "common/date_time.h"
|
||||
#include "common/ebml.h"
|
||||
#include "common/iso639.h"
|
||||
@ -349,7 +349,7 @@ change_c::get_semantic() {
|
||||
return find_ebml_semantic(libmatroska::KaxSegment::ClassInfos, m_property.m_callbacks->GlobalId);
|
||||
}
|
||||
|
||||
change_cptr
|
||||
std::vector<change_cptr>
|
||||
change_c::parse_spec(change_c::change_type_e type,
|
||||
const std::string &spec) {
|
||||
std::string name, value;
|
||||
@ -368,14 +368,34 @@ change_c::parse_spec(change_c::change_type_e type,
|
||||
if (name.empty())
|
||||
throw std::runtime_error(Y("missing property name"));
|
||||
|
||||
if ( mtx::included_in(type, ct_add, ct_set)
|
||||
&& (name == "language")) {
|
||||
auto language_opt = mtx::iso639::look_up(value);
|
||||
if (!language_opt)
|
||||
throw std::runtime_error{fmt::format(("invalid ISO 639-2 language code '{0}'"), value)};
|
||||
if (mtx::included_in(name, "language", "language-ietf"))
|
||||
return make_change_for_language(type, name, value);
|
||||
|
||||
value = language_opt->iso639_2_code;
|
||||
return { std::make_shared<change_c>(type, name, value) };
|
||||
}
|
||||
|
||||
std::vector<change_cptr>
|
||||
change_c::make_change_for_language(change_c::change_type_e type,
|
||||
std::string const &name,
|
||||
std::string const &value) {
|
||||
std::vector<change_cptr> changes;
|
||||
|
||||
if (type == ct_delete) {
|
||||
if (name == "language")
|
||||
changes.emplace_back(std::make_shared<change_c>(ct_delete, "language", value));
|
||||
changes.emplace_back(std::make_shared<change_c>(ct_delete, "language-ietf", value));
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
return std::make_shared<change_c>(type, name, value);
|
||||
auto language = mtx::bcp47::language_c::parse(value);
|
||||
if (!language.is_valid())
|
||||
throw std::runtime_error{fmt::format(Y("invalid language tag '{0}': {1}"), value, language.get_error())};
|
||||
|
||||
if (language.has_valid_iso639_code() && (name == "language"))
|
||||
changes.push_back(std::make_shared<change_c>(type, "language", language.get_iso639_2_code()));
|
||||
|
||||
changes.push_back(std::make_shared<change_c>(type, "language-ietf", language.format()));
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ public:
|
||||
void execute(EbmlMaster *master, EbmlMaster *sub_master);
|
||||
|
||||
public:
|
||||
static change_cptr parse_spec(change_type_e type, std::string const &spec);
|
||||
static std::vector<change_cptr> parse_spec(change_type_e type, std::string const &spec);
|
||||
static std::vector<change_cptr> make_change_for_language(change_type_e type, std::string const &name, std::string const &value);
|
||||
|
||||
protected:
|
||||
void parse_ascii_string();
|
||||
|
@ -186,6 +186,9 @@ propedit_cli_parser_c::list_property_names_for_table(const std::vector<property_
|
||||
mxinfo(fmt::format(Y("Elements in the category '{0}' ('--edit {1}'):\n"), title, edit_spec));
|
||||
|
||||
for (auto &property : table) {
|
||||
if (property.m_title.get_untranslated().empty())
|
||||
continue;
|
||||
|
||||
auto name = fmt::format("{0:<{1}} | {2:<2} |", property.m_name, max_name_len, ebml_type_map[property.m_type]);
|
||||
auto description = property.m_title.get_translated()
|
||||
+ ": "
|
||||
|
@ -52,7 +52,8 @@ segment_info_target_c::look_up_property_elements() {
|
||||
void
|
||||
segment_info_target_c::add_change(change_c::change_type_e type,
|
||||
const std::string &spec) {
|
||||
m_changes.push_back(change_c::parse_spec(type, spec));
|
||||
for (auto const &change : change_c::parse_spec(type, spec))
|
||||
m_changes.push_back(change);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -64,7 +64,8 @@ track_target_c::look_up_property_elements() {
|
||||
void
|
||||
track_target_c::add_change(change_c::change_type_e type,
|
||||
const std::string &spec) {
|
||||
m_changes.push_back(change_c::parse_spec(type, spec));
|
||||
for (auto const &change : change_c::parse_spec(type, spec))
|
||||
m_changes.push_back(change);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -167,7 +167,7 @@ T_318ui_locale_invalid:ok:passed:20111016-192531:0.021014802
|
||||
T_319wav_with_pcm_detected_as_dts:9a953abe9bd45f0a40249a3e155d7038:passed:20111016-224416:0.059853624
|
||||
T_320ts_aac:0a6e8b4ce6b07da206f2cf4bad1cd0c9:passed:20111022-140411:0.693145547
|
||||
T_321vc1_without_markers:e00284bc45738c8a8661e9667121790f:passed:20111104-003839:1.584477691
|
||||
T_322propedit_track_headers:785209f2dc35ad6177bea2ca6e43198f-ffc1ef67684cc9dd8626a4a7521e72ee-d2d12b7f8d1b036e4da6d0905b6107f0-4527b0737d21e47b6daa820806980abc-7bb13b6b10f063d944c4218df86c2f19:passed:20111203-152145:0.677404829
|
||||
T_322propedit_track_headers:785209f2dc35ad6177bea2ca6e43198f-ffc1ef67684cc9dd8626a4a7521e72ee-d2d12b7f8d1b036e4da6d0905b6107f0-9d9f4b00040791a912599b3bc8bc3056-efe56b89f19d9f4678ba2502447fcbb1:passed:20111203-152145:0.677404829
|
||||
T_323propedit_segment_info:785209f2dc35ad6177bea2ca6e43198f-0baf1cb46e7d365580b51aa4452551d6-d6cd21681b8544aa730744f128d46fd7:passed:20111203-152845:0.425794709
|
||||
T_324propedit_chapters:785209f2dc35ad6177bea2ca6e43198f-a9255d40de93e2731aaead0a746e582f-4cb0011aa862cb6d568e5ea5819ced90-072db741a4314c1c8facd4a4503e6f8d-1a271a88175960973efa641efa776aa5-ca8e205e4da2d3956b389642e8eda4bf-97fac7e0f65c5e419213ceeaf3f5c033-eb251b6ec5c49dc0caf28aa28bb5fda3-5aa640f146966af8b53456ddfbb999a7-d41d8cd98f00b204e9800998ecf8427e:passed:20111203-154502:0.736303091
|
||||
T_325propedit_tags:785209f2dc35ad6177bea2ca6e43198f-26ad4ab0491d76d9fb6f57b4a4b35400-cf5d35e5df0055c835c2998d69237c81-3a66efe256067a1cc6c08a130e915f66-cf5d35e5df0055c835c2998d69237c81-3a66efe256067a1cc6c08a130e915f66-704c6f50d8563790132f2213d3bf512a-930b89d9247818492f9e529e52fe97ce-74438375c40b7c3a77fbc894ee7d3acc-9c36e36e5810b0c42501f19c4d2c8b0f-74438375c40b7c3a77fbc894ee7d3acc-9c36e36e5810b0c42501f19c4d2c8b0f-dc4f9c9e12a584f12ad4c5f181a5d731-14f4960f62029211155dd9b137e532a1-e126ac5e6a97297f4ee14cfd648e1e33-d41d8cd98f00b204e9800998ecf8427e:passed:20111203-160727:1.314514241
|
||||
@ -371,7 +371,7 @@ T_522mpeg_1_2_es_no_start_code_at_beginning:cf63c8454526e94c6947a0b72e7963cf:pas
|
||||
T_523mpeg_ts_pes_size_0:3c26e56c1ade788914fa9c038949d208-35a8e3a06d95bb550f6e487ed5983955:passed:20151230-221825:1.635929691
|
||||
T_524mpeg2_misdetected_as_truehd:dacc8284272cc17cb3915b479b4f771a:passed:20160102-222743:1.10526128
|
||||
T_525truehd_doesnt_start_with_sync_frame:90300695ef1b9a99d4820f1e8432fc61:passed:20160104-205804:0.313378755
|
||||
T_526propedit_bibliographic_and_terminology_iso_639_2:e126a1c86a92197f170f8ea1d81c59f5-f5cae62cfde66fb164f576e7b450db0f-e126a1c86a92197f170f8ea1d81c59f5-f5cae62cfde66fb164f576e7b450db0f:passed:20160108-105234:0.538417963
|
||||
T_526propedit_bibliographic_and_terminology_iso_639_2:e126a1c86a92197f170f8ea1d81c59f5-4ce6cdc710bab390c47d02af20d75d9d-e126a1c86a92197f170f8ea1d81c59f5-4ce6cdc710bab390c47d02af20d75d9d:passed:20160108-105234:0.538417963
|
||||
T_527quicktime_v1_sound_stsd_zero_values:24e3e71012b051eef2045da95f7d7ae5:passed:20160117-112706:0.011153053
|
||||
T_528handbrake_chapter_uids:7da6ce990513c85f2a95a1c0ce394224:passed:20160119-173353:0.051508955
|
||||
T_529aac_program_config_element_with_empty_comment_at_end:66cf569e9f3f569840abc1c2381525d3:passed:20160124-120513:0.014071844
|
||||
@ -454,7 +454,7 @@ T_605h264_changing_sps_pps_wrong_frame_order_and_timestamps:c8374c608c49a4bf3fcd
|
||||
T_606aac_960_samples_per_frame:0d2bb8e38cfd2f4c9f0debcf65dba8e6-caa372cdbb838306ba653f16cc5b38a4:passed:20170720-215449:0.065007779
|
||||
T_607wave64:7be4fd1445503d8e31d7c568b230cd0d-dfa9c3fa3c83d3b4db8df42d84768d9e:passed:20170721-221321:0.021307011
|
||||
T_608ui_locale_ro_RO:3a6386df8e8d7aefb9258f070615b27d-0136434e2e22ebcc806ee944cdd2b853:passed:20170722-160005:0.021529144
|
||||
T_609propedit_video_colour_attributes:8f16c74ee8ab632fe89dbfdcebf83216+424ec608152307bf15baa9790654f648+92bdbbe1d99c51de6313b05b99c5f6eb+10b15af348a535b79ef6189a6e98db9b-2a7687d3d58c56985c2736918b02ffc7+ad956a57b7362856508c06a6c3d521a3+c62043ecabb9fbaf8b240b427e94b424+575734af498ee20c6a0afccdfa3201af:passed:20170803-210425:0.478005629
|
||||
T_609propedit_video_colour_attributes:8f16c74ee8ab632fe89dbfdcebf83216+424ec608152307bf15baa9790654f648+92bdbbe1d99c51de6313b05b99c5f6eb+10b15af348a535b79ef6189a6e98db9b-6a9694c62ec4cdbffdc60d904c92afdd+f7d3a407e374b3eaea61db87e5730973+b1a8ba4e930d7b66a7ea4a87d6df04c3+d1e4ecc4132174072aae526774311902:passed:20170803-210425:0.478005629
|
||||
T_610video_projection:a64e69ec7447f6cbc9c8963be13d3886-a64e69ec7447f6cbc9c8963be13d3886-711a95a1bb206e57f68132cfbfdbbaa3:passed:20170813-094000:0.147278453
|
||||
T_611info_null_pointer_dereference_for_ebmlbinary:68d2ebe0a701fffbcc5b5f245f1abbef:passed:20170813-104016:0.012946476
|
||||
T_612dts_provided_timestamp_used_too_early:1154ffd2536b05b810cb72586f4f4bb1:passed:20170813-175153:0.010423057
|
||||
@ -550,3 +550,4 @@ T_701subtitles_duration_rounding:fd11b1d9a4c6a983423a0d3ddca6b83b:passed:2020080
|
||||
T_702block_addition_mapping:ee9d0bf3f91415ab9d391d2abce79666-0b320131674f0e1876b0b210de02588f:passed:20200801-175839:0.377324674
|
||||
T_703bcp47_mkvmerge_tracks:d9e34751bc172b2e248317ac0ea26724-ok-1cc974de8570fbce15a7759c13c90f27-ok-e413c81bf9fcec35831c9b48b97761ed-ok-d245d8d0cb66f2f726a00f889e545421-ok-631e3325f78490f0b004d7f72d34ff86-ok-e126a1c86a92197f170f8ea1d81c59f5-ok-60270bfdcdfcd67a85e9a193d37a9211-ok-e837f9c1b89b7890cf0de6d6f5c5467a-ok-ba9f9203859f91ea16d5e7355e0ee728-ok-44efdba5b8df349cb86f542d094053a7-ok-ok-391b4322e8b21f4cdd516c1852b2ad62-ok-e0f4f807e1a97e05debd8a4a97765f8d-ok-8906500e73d32c42593a082e99bf937d-ok-81d85351687dc6e02e5a6ea36556b9be-ok-391b4322e8b21f4cdd516c1852b2ad62-ok-30ff508c184daa58810ce79a7a4d3d21-ok-60270bfdcdfcd67a85e9a193d37a9211-2a0a8a9fd62b6e8eb0c3fea076d68b80-ok-60270bfdcdfcd67a85e9a193d37a9211-77553e5b8eff562fb00e6222a60f9960-ok-60270bfdcdfcd67a85e9a193d37a9211-2a0a8a9fd62b6e8eb0c3fea076d68b80-ok-60270bfdcdfcd67a85e9a193d37a9211-1913fe33a25e4e3d928424828dc7be1b-ok-60270bfdcdfcd67a85e9a193d37a9211-1913fe33a25e4e3d928424828dc7be1b-ok-60270bfdcdfcd67a85e9a193d37a9211-2a0a8a9fd62b6e8eb0c3fea076d68b80-ok:passed:20200818-174121:0.0
|
||||
T_704bcp47_mkvmerge_chapters:7671e1a51985f55000eb878b962ebe2e-ok-5ca72b2c8cb7acda9db97d7be08ef246-ok-e95ca91dee4ef8ec8b03803bad2d4885-ok-0c6fc203244d4c0ac6efd6cda42404df-ok-0c6fc203244d4c0ac6efd6cda42404df-ok-0c6fc203244d4c0ac6efd6cda42404df-ok-a138c99228c4ea201eb21cb8021329f7-ok-49f0c8107a766c65fcc0a13f63bb4d49-ok-8d22672bb5b5bcfecd63f46bbfc90b2b-ok:passed:20200818-180751:0.32214628
|
||||
T_705bcp47_propedit_language_ietf:d9e34751bc172b2e248317ac0ea26724-und+und+ok+ger+de_CH+ok+ger+pt_BR+ok+ger++ok+spa+es_MX+ok+eng++ok:passed:20200822-114509:0.096933015
|
||||
|
35
tests/test-705bcp47_propedit_language_ietf.rb
Executable file
35
tests/test-705bcp47_propedit_language_ietf.rb
Executable file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/ruby -w
|
||||
|
||||
# T_705propedit_language_ietf
|
||||
describe "mkvpropedit / language-ietf"
|
||||
|
||||
def verify_languages language, language_ietf
|
||||
props = identify_json(tmp)["tracks"][0]["properties"]
|
||||
result = (props["language"] == language) && (props["language_ietf"] == language_ietf) ? "ok" : "bad"
|
||||
|
||||
[ props["language"], (props["language_ietf"] || '').gsub(%r{-}, '_'), result ]
|
||||
end
|
||||
|
||||
test_merge "data/subtitles/srt/vde-utf-8-bom.srt", :keep_tmp => true
|
||||
|
||||
test "language-ietf" do
|
||||
result = []
|
||||
result += verify_languages("und", "und")
|
||||
|
||||
propedit tmp, "--edit track:1 --set language=de-CH"
|
||||
result += verify_languages("ger", "de-CH")
|
||||
|
||||
propedit tmp, "--edit track:1 --set language-ietf=pt-BR"
|
||||
result += verify_languages("ger", "pt-BR")
|
||||
|
||||
propedit tmp, "--edit track:1 --delete language-ietf"
|
||||
result += verify_languages("ger", nil)
|
||||
|
||||
propedit tmp, "--edit track:1 --set language=es-MX"
|
||||
result += verify_languages("spa", "es-MX")
|
||||
|
||||
propedit tmp, "--edit track:1 --delete language"
|
||||
result += verify_languages("eng", nil)
|
||||
|
||||
result.join('+')
|
||||
end
|
Loading…
Reference in New Issue
Block a user