This test requires that the OS language settings be English so the --subs-match-os-language option is actually testable. In Linux, this can be done by just setting LANG and it always will work. For macOS and Windows, we use the OS APIs to get the languages and let the test proceed if we find English. Gracefully fail and skip otherwise.
Unified · Split
| @@ -16,8 +16,65 @@ · 15 unmodified lines | |||
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <unistd.h> | 18 | #include <unistd.h> |
| 19 | |||
| 20 | #ifdef __APPLE__ | ||
| 21 | #include <CoreFoundation/CoreFoundation.h> | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #ifdef _WIN32 | ||
| 25 | #include <windows.h> | ||
| 26 | #endif | ||
| 27 | |||
| 19 | #include "libmpv_common.h" | 28 | #include "libmpv_common.h" |
| 20 | 29 | ||
| 30 | static bool have_english_locale(void) | ||
| 31 | { | ||
| 32 | #ifdef __APPLE__ | ||
| 33 | CFArrayRef arr = CFLocaleCopyPreferredLanguages(); | ||
| 34 | if (!arr) | ||
| 35 | return false; | ||
| 36 | CFIndex count = CFArrayGetCount(arr); | ||
| 37 | if (!count) | ||
| 38 | return false; | ||
| 39 | |||
| 40 | bool ret = false; | ||
| 41 | CFRange range = CFRangeMake(0, 2); | ||
| 42 | CFStringRef en = CFStringCreateWithCString(NULL, "en", kCFStringEncodingMacRoman); | ||
| 43 | for (CFIndex i = 0; i < count; i++) { | ||
| 44 | CFStringRef cfstr = CFArrayGetValueAtIndex(arr, i); | ||
| 45 | if (CFStringCompareWithOptions(cfstr, en, range, 0) == 0) { | ||
| 46 | ret = true; | ||
| 47 | break; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | CFRelease(en); | ||
| 51 | return ret; | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #ifdef _WIN32 | ||
| 55 | ULONG count = 0; | ||
| 56 | ULONG size = 0; | ||
| 57 | wchar_t buf[1024]; | ||
| 58 | |||
| 59 | if (GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &count, buf, &size)) { | ||
| 60 | for (ULONG pos = 0; buf[pos]; pos += wcslen(buf + pos) + 1) { | ||
| 61 | if (wcsncmp(buf + pos, L"en", 2) == 0) | ||
| 62 | return true; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | if (GetSystemPreferredUILanguages(MUI_LANGUAGE_NAME, &count, buf, &size)) { | ||
| 67 | for (ULONG pos = 0; buf[pos]; pos += wcslen(buf + pos) + 1) { | ||
| 68 | if (wcsncmp(buf + pos, L"en", 2) == 0) | ||
| 69 | return true; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | return false; | ||
| 74 | #endif | ||
| 75 | return true; | ||
| 76 | } | ||
| 77 | |||
| 21 | static void check_string(const char *property, const char *expect) | 78 | static void check_string(const char *property, const char *expect) |
| 22 | { | 79 | { |
| 23 | char *result_string; | 80 | char *result_string; |
| @@ -84,6 +141,15 @@ static void test_track_selection(char *file, char *path) · 60 unmodified lines | |||
| 84 | check_api_error(mpv_set_property_string(ctx, "subs-fallback", "yes")); | 141 | check_api_error(mpv_set_property_string(ctx, "subs-fallback", "yes")); |
| 85 | reload_file(path); | 142 | reload_file(path); |
| 86 | check_string("current-tracks/sub/selected", "yes"); | 143 | check_string("current-tracks/sub/selected", "yes"); |
| 144 | } else if (strcmp(file, "locale.mkv") == 0) { | ||
| 145 | // default english subs | ||
| 146 | reload_file(path); | ||
| 147 | check_string("current-tracks/sub/lang", "eng"); | ||
| 148 | |||
| 149 | // default german subs | ||
| 150 | check_api_error(mpv_set_property_string(ctx, "subs-match-os-language", "no")); | ||
| 151 | reload_file(path); | ||
| 152 | check_string("current-tracks/sub/lang", "ger"); | ||
| 87 | } else if (strcmp(file, "multilang.mkv") == 0) { | 153 | } else if (strcmp(file, "multilang.mkv") == 0) { |
| 88 | // --alang=jpn should select forced jpn subs | 154 | // --alang=jpn should select forced jpn subs |
| 89 | check_api_error(mpv_set_property_string(ctx, "alang", "jpn")); | 155 | check_api_error(mpv_set_property_string(ctx, "alang", "jpn")); |
| @@ -186,6 +252,11 @@ int main(int argc, char *argv[]) · 96 unmodified lines | |||
| 186 | if (argc < 3) | 252 | if (argc < 3) |
| 187 | return 1; | 253 | return 1; |
| 188 | 254 | ||
| 255 | if (!strcmp(argv[1], "locale.mkv") && !have_english_locale()) { | ||
| 256 | printf("Non English language detected. Skipping locale test.\n"); | ||
| 257 | return 77; | ||
| 258 | } | ||
| 259 | |||
| 189 | ctx = mpv_create(); | 260 | ctx = mpv_create(); |
| 190 | if (!ctx) | 261 | if (!ctx) |
| 191 | return 1; | 262 | return 1; |
| @@ -32,6 +32,11 @@ samples = { · 31 unmodified lines | |||
| 32 | '-disposition:s:0', 'forced', '@OUTPUT@'], | 32 | '-disposition:s:0', 'forced', '@OUTPUT@'], |
| 33 | 'eng_no_default.mkv': | 33 | 'eng_no_default.mkv': |
| 34 | [ffmpeg, common_args, '@OUTPUT@'], | 34 | [ffmpeg, common_args, '@OUTPUT@'], |
| 35 | 'locale.mkv': | ||
| 36 | [ffmpeg, '-v', 'error', '-y', '-i', video, '-i', audio, '-f', 'srt', '-i', sub, '-i', sub, | ||
| 37 | '-c', 'copy', '-map', '0:0', '-map', '1:0', '-map', '2:0', '-map', '3:0', '-metadata:s:s:0', | ||
| 38 | 'language=ger', '-metadata:s:s:1', 'language=eng', '-disposition:s:0', 'default', | ||
| 39 | '-disposition:s:1', 'default', '@OUTPUT@'], | ||
| 35 | 'multilang.mkv': | 40 | 'multilang.mkv': |
| 36 | [ffmpeg, '-v', 'error', '-y', '-i', video, '-i', audio, '-i', audio, '-i', audio, '-i', audio, | 41 | [ffmpeg, '-v', 'error', '-y', '-i', video, '-i', audio, '-i', audio, '-i', audio, '-i', audio, |
| 37 | '-f', 'srt', '-i', sub, '-i', sub, '-i', sub, '-i', sub, '-c', 'copy', '-map', '0:0', | 42 | '-f', 'srt', '-i', sub, '-i', sub, '-i', sub, '-i', sub, '-c', 'copy', '-map', '0:0', |
| @@ -57,9 +62,10 @@ foreach name, cmd: samples · 19 unmodified lines | |||
| 57 | depends: [video, audio], | 62 | depends: [video, audio], |
| 58 | command: cmd, | 63 | command: cmd, |
| 59 | ) | 64 | ) |
| 65 | env = name == 'locale.mkv' ? 'LANG=C' : [] | ||
| 60 | testname = 'libmpv-test-' + name | 66 | testname = 'libmpv-test-' + name |
| 61 | exe = executable(testname, '../libmpv_test_track_selection.c', | 67 | exe = executable(testname, '../libmpv_test_track_selection.c', |
| 62 | include_directories: incdir, link_with: libmpv) | 68 | include_directories: incdir, link_with: libmpv) |
| 63 | test(testname, exe, args: [name, target.full_path()], | 69 | test(testname, exe, args: [name, target.full_path()], |
| 64 | depends: target, suite: 'libmpv') | 70 | depends: target, env: env, suite: 'libmpv') |
| 65 | endforeach | 71 | endforeach |