From 5a3b54c78ce63d899f76dbb3db72e4894b40bd53 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 03:13:14 +0200 Subject: Merging upstream version 0.38.0. Signed-off-by: Daniel Baumann --- TOOLS/dylib-unhell.py | 181 ------------------- TOOLS/dylib_unhell.py | 268 ++++++++++++++++++++++++++++ TOOLS/gen-interface-changes.py | 83 +++++++++ TOOLS/lua/autocrop.lua | 2 +- TOOLS/lua/autodeint.lua | 2 +- TOOLS/lua/autoload.lua | 30 +++- TOOLS/lua/skip-logo.lua | 2 +- TOOLS/matroska.py | 3 + TOOLS/osxbundle.py | 43 +++-- TOOLS/osxbundle/mpv.app/Contents/Info.plist | 2 + 10 files changed, 407 insertions(+), 209 deletions(-) delete mode 100755 TOOLS/dylib-unhell.py create mode 100755 TOOLS/dylib_unhell.py create mode 100755 TOOLS/gen-interface-changes.py (limited to 'TOOLS') diff --git a/TOOLS/dylib-unhell.py b/TOOLS/dylib-unhell.py deleted file mode 100755 index c41d200..0000000 --- a/TOOLS/dylib-unhell.py +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/env python3 - -import re -import os -import sys -import shutil -import subprocess -from functools import partial - -sys_re = re.compile("^/System") -usr_re = re.compile("^/usr/lib/") -exe_re = re.compile("@executable_path") - -def is_user_lib(objfile, libname): - return not sys_re.match(libname) and \ - not usr_re.match(libname) and \ - not exe_re.match(libname) and \ - not "libobjc." in libname and \ - not "libSystem." in libname and \ - not "libc." in libname and \ - not "libgcc." in libname and \ - not os.path.basename(libname) == 'Python' and \ - not os.path.basename(objfile) in libname and \ - not "libswift" in libname - -def otool(objfile, rapths): - command = "otool -L '%s' | grep -e '\t' | awk '{ print $1 }'" % objfile - output = subprocess.check_output(command, shell = True, universal_newlines=True) - libs = set(filter(partial(is_user_lib, objfile), output.split())) - - libs_resolved = set() - libs_relative = set() - for lib in libs: - lib_path = resolve_lib_path(objfile, lib, rapths) - libs_resolved.add(lib_path) - if lib_path != lib: - libs_relative.add(lib) - - return libs_resolved, libs_relative - -def get_rapths(objfile): - rpaths = [] - command = "otool -l '%s' | grep -A2 LC_RPATH | grep path" % objfile - pathRe = re.compile("^\s*path (.*) \(offset \d*\)$") - - try: - result = subprocess.check_output(command, shell = True, universal_newlines=True) - except: - return rpaths - - for line in result.splitlines(): - rpaths.append(pathRe.search(line).group(1).strip()) - - return rpaths - -def get_rpaths_dev_tools(binary): - command = "otool -l '%s' | grep -A2 LC_RPATH | grep path | grep \"Xcode\|CommandLineTools\"" % binary - result = subprocess.check_output(command, shell = True, universal_newlines=True) - pathRe = re.compile("^\s*path (.*) \(offset \d*\)$") - output = [] - - for line in result.splitlines(): - output.append(pathRe.search(line).group(1).strip()) - - return output - -def resolve_lib_path(objfile, lib, rapths): - if os.path.exists(lib): - return lib - - if lib.startswith('@rpath/'): - lib = lib[len('@rpath/'):] - for rpath in rapths: - lib_path = os.path.join(rpath, lib) - if os.path.exists(lib_path): - return lib_path - elif lib.startswith('@loader_path/'): - lib = lib[len('@loader_path/'):] - lib_path = os.path.normpath(os.path.join(objfile, lib)) - if os.path.exists(lib_path): - return lib_path - - raise Exception('Could not resolve library: ' + lib) - -def install_name_tool_change(old, new, objfile): - subprocess.call(["install_name_tool", "-change", old, new, objfile], stderr=subprocess.DEVNULL) - -def install_name_tool_id(name, objfile): - subprocess.call(["install_name_tool", "-id", name, objfile], stderr=subprocess.DEVNULL) - -def install_name_tool_add_rpath(rpath, binary): - subprocess.call(["install_name_tool", "-add_rpath", rpath, binary]) - -def install_name_tool_delete_rpath(rpath, binary): - subprocess.call(["install_name_tool", "-delete_rpath", rpath, binary]) - -def libraries(objfile, result = dict(), result_relative = set(), rapths = []): - rapths = get_rapths(objfile) + rapths - libs_list, libs_relative = otool(objfile, rapths) - result[objfile] = libs_list - result_relative |= libs_relative - - for lib in libs_list: - if lib not in result: - libraries(lib, result, result_relative, rapths) - - return result, result_relative - -def lib_path(binary): - return os.path.join(os.path.dirname(binary), 'lib') - -def lib_name(lib): - return os.path.join("@executable_path", "lib", os.path.basename(lib)) - -def process_libraries(libs_dict, libs_dyn, binary): - libs_set = set(libs_dict) - # Remove binary from libs_set to prevent a duplicate of the binary being - # added to the libs directory. - libs_set.remove(binary) - - for src in libs_set: - name = lib_name(src) - dst = os.path.join(lib_path(binary), os.path.basename(src)) - - shutil.copy(src, dst) - os.chmod(dst, 0o755) - install_name_tool_id(name, dst) - - if src in libs_dict[binary]: - install_name_tool_change(src, name, binary) - - for p in libs_set: - if p in libs_dict[src]: - install_name_tool_change(p, lib_name(p), dst) - - for lib in libs_dyn: - install_name_tool_change(lib, lib_name(lib), dst) - - for lib in libs_dyn: - install_name_tool_change(lib, lib_name(lib), binary) - -def process_swift_libraries(binary): - command = ['xcrun', '--find', 'swift-stdlib-tool'] - swiftStdlibTool = subprocess.check_output(command, universal_newlines=True).strip() - # from xcode11 on the dynamic swift libs reside in a separate directory from - # the std one, might need versioned paths for future swift versions - swiftLibPath = os.path.join(swiftStdlibTool, '../../lib/swift-5.0/macosx') - swiftLibPath = os.path.abspath(swiftLibPath) - - command = [swiftStdlibTool, '--copy', '--platform', 'macosx', '--scan-executable', binary, '--destination', lib_path(binary)] - - if os.path.exists(swiftLibPath): - command.extend(['--source-libraries', swiftLibPath]) - - subprocess.check_output(command, universal_newlines=True) - - print(">> setting additional rpath for swift libraries") - install_name_tool_add_rpath("@executable_path/lib", binary) - -def remove_dev_tools_rapths(binary): - for path in get_rpaths_dev_tools(binary): - install_name_tool_delete_rpath(path, binary) - -def main(): - binary = os.path.abspath(sys.argv[1]) - if not os.path.exists(lib_path(binary)): - os.makedirs(lib_path(binary)) - print(">> gathering all linked libraries") - libs, libs_rel = libraries(binary) - - print(">> copying and processing all linked libraries") - process_libraries(libs, libs_rel, binary) - - print(">> removing rpath definitions towards dev tools") - remove_dev_tools_rapths(binary) - - print(">> copying and processing swift libraries") - process_swift_libraries(binary) - -if __name__ == "__main__": - main() diff --git a/TOOLS/dylib_unhell.py b/TOOLS/dylib_unhell.py new file mode 100755 index 0000000..c885969 --- /dev/null +++ b/TOOLS/dylib_unhell.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python3 + +import re +import os +import sys +import shutil +import subprocess +import json +from functools import partial + +sys_re = re.compile("^/System") +usr_re = re.compile("^/usr/lib/") +exe_re = re.compile("@executable_path") + +def is_user_lib(objfile, libname): + return not sys_re.match(libname) and \ + not usr_re.match(libname) and \ + not exe_re.match(libname) and \ + not "libobjc." in libname and \ + not "libSystem." in libname and \ + not "libc." in libname and \ + not "libgcc." in libname and \ + not os.path.basename(libname) == 'Python' and \ + not os.path.basename(objfile) in libname and \ + not "libswift" in libname + +def otool(objfile, rapths): + command = "otool -L '%s' | grep -e '\t' | awk '{ print $1 }'" % objfile + output = subprocess.check_output(command, shell = True, universal_newlines=True) + libs = set(filter(partial(is_user_lib, objfile), output.split())) + + libs_resolved = set() + libs_relative = set() + for lib in libs: + lib_path = resolve_lib_path(objfile, lib, rapths) + libs_resolved.add(lib_path) + if lib_path != lib: + libs_relative.add(lib) + + return libs_resolved, libs_relative + +def get_rapths(objfile): + rpaths = [] + command = "otool -l '%s' | grep -A2 LC_RPATH | grep path" % objfile + pathRe = re.compile(r"^\s*path (.*) \(offset \d*\)$") + + try: + result = subprocess.check_output(command, shell = True, universal_newlines=True) + except: + return rpaths + + for line in result.splitlines(): + line_clean = pathRe.search(line).group(1).strip() + # resolve @loader_path + if line_clean.startswith('@loader_path/'): + line_clean = line_clean[len('@loader_path/'):] + line_clean = os.path.normpath(os.path.join(os.path.dirname(objfile), line_clean)) + rpaths.append(line_clean) + + return rpaths + +def get_rpaths_dev_tools(binary): + command = "otool -l '%s' | grep -A2 LC_RPATH | grep path | grep \"Xcode\\|CommandLineTools\"" % binary + result = subprocess.check_output(command, shell = True, universal_newlines=True) + pathRe = re.compile(r"^\s*path (.*) \(offset \d*\)$") + output = [] + + for line in result.splitlines(): + output.append(pathRe.search(line).group(1).strip()) + + return output + +def resolve_lib_path(objfile, lib, rapths): + if os.path.exists(lib): + return lib + + if lib.startswith('@rpath/'): + lib = lib[len('@rpath/'):] + for rpath in rapths: + lib_path = os.path.join(rpath, lib) + if os.path.exists(lib_path): + return lib_path + elif lib.startswith('@loader_path/'): + lib = lib[len('@loader_path/'):] + lib_path = os.path.normpath(os.path.join(objfile, lib)) + if os.path.exists(lib_path): + return lib_path + + raise Exception('Could not resolve library: ' + lib) + +def check_vulkan_max_version(version): + try: + result = subprocess.check_output("pkg-config vulkan --max-version=" + version, shell = True) + return True + except: + return False + +def get_homebrew_prefix(): + # set default to standard ARM path, intel path is already in the vulkan loader search array + result = "/opt/homebrew" + try: + result = subprocess.check_output("brew --prefix", universal_newlines=True, shell=True, stderr=subprocess.DEVNULL).strip() + except: + pass + + return result + +def install_name_tool_change(old, new, objfile): + subprocess.call(["install_name_tool", "-change", old, new, objfile], stderr=subprocess.DEVNULL) + +def install_name_tool_id(name, objfile): + subprocess.call(["install_name_tool", "-id", name, objfile], stderr=subprocess.DEVNULL) + +def install_name_tool_add_rpath(rpath, binary): + subprocess.call(["install_name_tool", "-add_rpath", rpath, binary]) + +def install_name_tool_delete_rpath(rpath, binary): + subprocess.call(["install_name_tool", "-delete_rpath", rpath, binary]) + +def libraries(objfile, result = dict(), result_relative = set(), rapths = []): + rapths = get_rapths(objfile) + rapths + libs_list, libs_relative = otool(objfile, rapths) + result[objfile] = libs_list + result_relative |= libs_relative + + for lib in libs_list: + if lib not in result: + libraries(lib, result, result_relative, rapths) + + return result, result_relative + +def lib_path(binary): + return os.path.join(os.path.dirname(binary), 'lib') + +def resources_path(binary): + return os.path.join(os.path.dirname(binary), '../Resources') + +def lib_name(lib): + return os.path.join("@executable_path", "lib", os.path.basename(lib)) + +def process_libraries(libs_dict, libs_dyn, binary): + libs_set = set(libs_dict) + # Remove binary from libs_set to prevent a duplicate of the binary being + # added to the libs directory. + libs_set.remove(binary) + + for src in libs_set: + name = lib_name(src) + dst = os.path.join(lib_path(binary), os.path.basename(src)) + + shutil.copy(src, dst) + os.chmod(dst, 0o755) + install_name_tool_id(name, dst) + + if src in libs_dict[binary]: + install_name_tool_change(src, name, binary) + + for p in libs_set: + if p in libs_dict[src]: + install_name_tool_change(p, lib_name(p), dst) + + for lib in libs_dyn: + install_name_tool_change(lib, lib_name(lib), dst) + + for lib in libs_dyn: + install_name_tool_change(lib, lib_name(lib), binary) + +def process_swift_libraries(binary): + command = ['xcrun', '--find', 'swift-stdlib-tool'] + swiftStdlibTool = subprocess.check_output(command, universal_newlines=True).strip() + # from xcode11 on the dynamic swift libs reside in a separate directory from + # the std one, might need versioned paths for future swift versions + swiftLibPath = os.path.join(swiftStdlibTool, '../../lib/swift-5.0/macosx') + swiftLibPath = os.path.abspath(swiftLibPath) + + command = [swiftStdlibTool, '--copy', '--platform', 'macosx', '--scan-executable', binary, '--destination', lib_path(binary)] + + if os.path.exists(swiftLibPath): + command.extend(['--source-libraries', swiftLibPath]) + + subprocess.check_output(command, universal_newlines=True) + + print(">> setting additional rpath for swift libraries") + install_name_tool_add_rpath("@executable_path/lib", binary) + +def process_vulkan_loader(binary, loaderName, loaderRelativeFolder, libraryNode): + # https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderDriverInterface.md#example-macos-driver-search-path + # https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderLayerInterface.md#macos-layer-discovery + loaderSystemSearchFolders = [ + os.path.join(os.path.expanduser("~"), ".config", loaderRelativeFolder), + os.path.join("/etc/xdg", loaderRelativeFolder), + os.path.join("/usr/local/etc", loaderRelativeFolder), + os.path.join("/etc", loaderRelativeFolder), + os.path.join(os.path.expanduser("~"), ".local/share", loaderRelativeFolder), + os.path.join("/usr/local/share", loaderRelativeFolder), + os.path.join("/usr/share/vulkan", loaderRelativeFolder), + os.path.join(get_homebrew_prefix(), 'share', loaderRelativeFolder), + ] + + loaderSystemFolder = "" + for loaderSystemSearchFolder in loaderSystemSearchFolders: + if os.path.exists(loaderSystemSearchFolder): + loaderSystemFolder = loaderSystemSearchFolder + break + + if not loaderSystemFolder: + print(">>> could not find loader folder " + loaderRelativeFolder) + return + + loaderBundleFolder = os.path.join(resources_path(binary), loaderRelativeFolder) + loaderSystemPath = os.path.join(loaderSystemFolder, loaderName) + loaderBundlePath = os.path.join(loaderBundleFolder, loaderName) + libraryRelativeFolder = "../../../Frameworks/" + + if not os.path.exists(loaderSystemPath): + print(">>> could not find loader " + loaderName) + return + + if not os.path.exists(loaderBundleFolder): + os.makedirs(loaderBundleFolder) + + loaderSystemFile = open(loaderSystemPath, 'r') + loaderJsonData = json.load(loaderSystemFile) + librarySystemPath = os.path.join(loaderSystemFolder, loaderJsonData[libraryNode]["library_path"]) + + if not os.path.exists(librarySystemPath): + print(">>> could not find loader library " + librarySystemPath) + return + + print(">>> modifiying and writing loader json " + loaderName) + loaderBundleFile = open(loaderBundlePath, 'w') + loaderLibraryName = os.path.basename(librarySystemPath) + loaderJsonData[libraryNode]["library_path"] = os.path.join(libraryRelativeFolder, loaderLibraryName) + json.dump(loaderJsonData, loaderBundleFile, indent=4) + + print(">>> copying loader library " + loaderLibraryName) + frameworkBundleFolder = os.path.join(loaderBundleFolder, libraryRelativeFolder) + if not os.path.exists(frameworkBundleFolder): + os.makedirs(frameworkBundleFolder) + shutil.copy(librarySystemPath, os.path.join(frameworkBundleFolder, loaderLibraryName)) + +def remove_dev_tools_rapths(binary): + for path in get_rpaths_dev_tools(binary): + install_name_tool_delete_rpath(path, binary) + +def process(binary): + binary = os.path.abspath(binary) + if not os.path.exists(lib_path(binary)): + os.makedirs(lib_path(binary)) + print(">> gathering all linked libraries") + libs, libs_rel = libraries(binary) + + print(">> copying and processing all linked libraries") + process_libraries(libs, libs_rel, binary) + + print(">> removing rpath definitions towards dev tools") + remove_dev_tools_rapths(binary) + + print(">> copying and processing swift libraries") + process_swift_libraries(binary) + + print(">> copying and processing vulkan loader") + process_vulkan_loader(binary, "MoltenVK_icd.json", "vulkan/icd.d", "ICD") + if check_vulkan_max_version("1.3.261.1"): + process_vulkan_loader(binary, "VkLayer_khronos_synchronization2.json", "vulkan/explicit_layer.d", "layer") + +if __name__ == "__main__": + process(sys.argv[1]) diff --git a/TOOLS/gen-interface-changes.py b/TOOLS/gen-interface-changes.py new file mode 100755 index 0000000..7f5435e --- /dev/null +++ b/TOOLS/gen-interface-changes.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +# Generate a new interface-changes.rst based on the entries in +# the interface-changes directory. + +# +# This file is part of mpv. +# +# mpv is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# mpv is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with mpv. If not, see . +# + +import pathlib +import sys +from shutil import which +from subprocess import check_output + +def add_new_entries(docs_dir, out, git): + changes_dir = pathlib.Path(docs_dir) / "interface-changes" + files = [] + for f in pathlib.Path(changes_dir).glob("*.txt"): + if f.is_file() and not f.name == "example.txt": + timestamp = check_output([git, "log", "--format=%ct", "-n", "1", "--", + f], encoding="UTF-8") + if timestamp: + files.append((f, timestamp)) + else: + print(f"Skipping file not tracked by git: {f.name}") + + files.sort(key=lambda x: x[1]) + for file in files: + with open(file[0].resolve(), "r") as f: + for line in f: + line = " - " + line.rstrip() + out.write(line + "\n") + +if __name__ == "__main__": + if len(sys.argv) < 2: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + + git = which('git') + if not git: + print("Unable to find git binary") + sys.exit(1) + + # Accept passing only the major version number and the full 0 version. + major_version = -1 + if sys.argv[1].isdigit(): + major_version = sys.argv[1] + else: + ver_split = sys.argv[1].split(".") + if len(ver_split) == 3 and ver_split[1].isdigit(): + major_version = ver_split[1] + + if major_version == -1: + print(f"Invalid version number: {sys.argv[1]}") + sys.exit(1) + + docs_dir = pathlib.Path(sys.argv[0]).resolve().parents[1] / "DOCS" + interface_changes = docs_dir / "interface-changes.rst" + with open(interface_changes, "r") as f: + lines = [line.rstrip() for line in f] + + ver_line = " --- mpv 0." + major_version + ".0 ---" + next_ver_line = " --- mpv 0." + str(int(major_version) + 1) + ".0 ---" + with open(interface_changes, "w", newline="\n") as f: + for line in lines: + if line == ver_line: + f.write(next_ver_line + "\n") + f.write(line + "\n") + if line == ver_line: + add_new_entries(docs_dir, f, git) diff --git a/TOOLS/lua/autocrop.lua b/TOOLS/lua/autocrop.lua index b9e1120..ea57d15 100644 --- a/TOOLS/lua/autocrop.lua +++ b/TOOLS/lua/autocrop.lua @@ -177,7 +177,7 @@ function detect_end() else mp.msg.error("No crop data.") mp.msg.info("Was the cropdetect filter successfully inserted?") - mp.msg.info("Does your version of ffmpeg/libav support AVFrame metadata?") + mp.msg.info("Does your version of FFmpeg support AVFrame metadata?") return end diff --git a/TOOLS/lua/autodeint.lua b/TOOLS/lua/autodeint.lua index b891c9a..4e92960 100644 --- a/TOOLS/lua/autodeint.lua +++ b/TOOLS/lua/autodeint.lua @@ -8,7 +8,7 @@ -- telecined and the interlacing field dominance. -- -- Based on this information, it may set mpv's ``deinterlace`` property (which --- usually inserts the yadif filter), or insert the ``pullup`` filter if the +-- usually inserts the bwdif filter), or insert the ``pullup`` filter if the -- content is telecined. It also sets field dominance with lavfi setfield. -- -- OPTIONS: diff --git a/TOOLS/lua/autoload.lua b/TOOLS/lua/autoload.lua index 4003cbc..e0cfeb2 100644 --- a/TOOLS/lua/autoload.lua +++ b/TOOLS/lua/autoload.lua @@ -73,17 +73,17 @@ function Split (s) return set end -EXTENSIONS_VIDEO = Set { +EXTENSIONS_VIDEO_DEFAULT = Set { '3g2', '3gp', 'avi', 'flv', 'm2ts', 'm4v', 'mj2', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ogv', 'rmvb', 'webm', 'wmv', 'y4m' } -EXTENSIONS_AUDIO = Set { +EXTENSIONS_AUDIO_DEFAULT = Set { 'aiff', 'ape', 'au', 'flac', 'm4a', 'mka', 'mp3', 'oga', 'ogg', 'ogm', 'opus', 'wav', 'wma' } -EXTENSIONS_IMAGES = Set { +EXTENSIONS_IMAGES_DEFAULT = Set { 'avif', 'bmp', 'gif', 'j2k', 'jp2', 'jpeg', 'jpg', 'jxl', 'png', 'svg', 'tga', 'tif', 'tiff', 'webp' } @@ -97,9 +97,21 @@ split_option_exts(true, true, true) function create_extensions() EXTENSIONS = {} - if o.videos then SetUnion(SetUnion(EXTENSIONS, EXTENSIONS_VIDEO), o.additional_video_exts) end - if o.audio then SetUnion(SetUnion(EXTENSIONS, EXTENSIONS_AUDIO), o.additional_audio_exts) end - if o.images then SetUnion(SetUnion(EXTENSIONS, EXTENSIONS_IMAGES), o.additional_image_exts) end + EXTENSIONS_VIDEO = {} + EXTENSIONS_AUDIO = {} + EXTENSIONS_IMAGES = {} + if o.videos then + SetUnion(SetUnion(EXTENSIONS_VIDEO, EXTENSIONS_VIDEO_DEFAULT), o.additional_video_exts) + SetUnion(EXTENSIONS, EXTENSIONS_VIDEO) + end + if o.audio then + SetUnion(SetUnion(EXTENSIONS_AUDIO, EXTENSIONS_AUDIO_DEFAULT), o.additional_audio_exts) + SetUnion(EXTENSIONS, EXTENSIONS_AUDIO) + end + if o.images then + SetUnion(SetUnion(EXTENSIONS_IMAGES, EXTENSIONS_IMAGES_DEFAULT), o.additional_image_exts) + SetUnion(EXTENSIONS, EXTENSIONS_IMAGES) + end end create_extensions() @@ -211,6 +223,12 @@ function scan_dir(path, current_file, dir_mode, separator, dir_depth, total_file end function find_and_add_entries() + local aborted = mp.get_property_native("playback-abort") + if aborted then + msg.debug("stopping: playback aborted") + return + end + local path = mp.get_property("path", "") local dir, filename = utils.split_path(path) msg.trace(("dir: %s, filename: %s"):format(dir, filename)) diff --git a/TOOLS/lua/skip-logo.lua b/TOOLS/lua/skip-logo.lua index 8e1f9da..ae66b22 100644 --- a/TOOLS/lua/skip-logo.lua +++ b/TOOLS/lua/skip-logo.lua @@ -232,7 +232,7 @@ local function read_frames() end end -mp.observe_property(meta_property, "none", function() +mp.observe_property(meta_property, "native", function() -- Ignore frames that are decoded/filtered during seeking. if seeking then return diff --git a/TOOLS/matroska.py b/TOOLS/matroska.py index 52bac48..61a33ff 100755 --- a/TOOLS/matroska.py +++ b/TOOLS/matroska.py @@ -92,6 +92,7 @@ elements_matroska = ( 'MaxBlockAdditionID, 55ee, uint', 'Name, 536e, str', 'Language, 22b59c, str', + 'LanguageBCP47, 22b59d, str', 'CodecID, 86, str', 'CodecPrivate, 63a2, binary', 'CodecName, 258688, str', @@ -206,6 +207,7 @@ elements_matroska = ( 'ChapterDisplay*, 80, sub', ( 'ChapString, 85, str', 'ChapLanguage*, 437c, str', + 'ChapLanguageBCP47*, 437d, str', 'ChapCountry*, 437e, str', ), ), @@ -224,6 +226,7 @@ elements_matroska = ( 'SimpleTag*, 67c8, sub', ( 'TagName, 45a3, str', 'TagLanguage, 447a, str', + 'TagLanguageBCP47, 447b, str', 'TagString, 4487, str', 'TagDefault, 4484, uint', ), diff --git a/TOOLS/osxbundle.py b/TOOLS/osxbundle.py index 98699e4..0e156a0 100755 --- a/TOOLS/osxbundle.py +++ b/TOOLS/osxbundle.py @@ -1,13 +1,11 @@ #!/usr/bin/env python3 import os import shutil -import sys import fileinput +import dylib_unhell +import subprocess from optparse import OptionParser -def sh(command): - return os.popen(command).read().strip() - def bundle_path(binary_name): return "%s.app" % binary_name @@ -24,11 +22,11 @@ def target_binary(binary_name): return os.path.join(target_directory(binary_name), os.path.basename(binary_name)) -def copy_bundle(binary_name): +def copy_bundle(binary_name, src_path): if os.path.isdir(bundle_path(binary_name)): shutil.rmtree(bundle_path(binary_name)) shutil.copytree( - os.path.join('TOOLS', 'osxbundle', bundle_name(binary_name)), + os.path.join(src_path, 'TOOLS', 'osxbundle', bundle_name(binary_name)), bundle_path(binary_name)) def copy_binary(binary_name): @@ -39,20 +37,24 @@ def apply_plist_template(plist_file, version): print(line.rstrip().replace('${VERSION}', version)) def sign_bundle(binary_name): - sh('codesign --force --deep -s - ' + bundle_path(binary_name)) - -def bundle_version(): - if os.path.exists('VERSION'): - x = open('VERSION') + sign_directories = ['Contents/Frameworks', 'Contents/MacOS'] + for dir in sign_directories: + resolved_dir = os.path.join(bundle_path(binary_name), dir) + for root, _dirs, files in os.walk(resolved_dir): + for f in files: + subprocess.run(['codesign', '--force', '-s', '-', os.path.join(root, f)]) + subprocess.run(['codesign', '--force', '-s', '-', bundle_path(binary_name)]) + +def bundle_version(src_path): + version = 'UNKNOWN' + version_path = os.path.join(src_path, 'VERSION') + if os.path.exists(version_path): + x = open(version_path) version = x.read() x.close() - else: - version = sh("./version.sh").strip() return version def main(): - version = bundle_version().rstrip() - usage = "usage: %prog [options] arg" parser = OptionParser(usage) parser.add_option("-s", "--skip-deps", action="store_false", dest="deps", @@ -61,14 +63,17 @@ def main(): (options, args) = parser.parse_args() - if len(args) != 1: + if len(args) < 1 or len(args) > 2: parser.error("incorrect number of arguments") else: binary_name = args[0] + src_path = args[1] if len(args) > 1 else "." + + version = bundle_version(src_path).rstrip() - print("Creating Mac OS X application bundle (version: %s)..." % version) + print("Creating macOS application bundle (version: %s)..." % version) print("> copying bundle skeleton") - copy_bundle(binary_name) + copy_bundle(binary_name, src_path) print("> copying binary") copy_binary(binary_name) print("> generating Info.plist") @@ -76,7 +81,7 @@ def main(): if options.deps: print("> bundling dependencies") - print(sh(" ".join(["TOOLS/dylib-unhell.py", target_binary(binary_name)]))) + dylib_unhell.process(target_binary(binary_name)) print("> signing bundle with ad-hoc pseudo identity") sign_bundle(binary_name) diff --git a/TOOLS/osxbundle/mpv.app/Contents/Info.plist b/TOOLS/osxbundle/mpv.app/Contents/Info.plist index e239dc7..eaa83ad 100644 --- a/TOOLS/osxbundle/mpv.app/Contents/Info.plist +++ b/TOOLS/osxbundle/mpv.app/Contents/Info.plist @@ -188,6 +188,8 @@ ${VERSION} NSHighResolutionCapable + LSApplicationCategoryType + public.app-category.games LSEnvironment MallocNanoZone -- cgit v1.2.3