Add Unlicense and ship ffmpeg's GPL license in release archives
The project is now public domain under the Unlicense (LICENSE, README). The packaged archives bundle GPL ffmpeg/ffprobe builds but did not include their license. fetch_ffmpeg.py now extracts the build's LICENSE.txt into ffmpeg/LICENSE.txt, and build.py --ffmpeg-dir copies it into the archive as ffmpeg-LICENSE.txt, failing before the PyInstaller run if it can't find one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
|
||||
Uses the GPL builds from https://github.com/BtbN/FFmpeg-Builds (newest stable
|
||||
release branch). The app finds ./ffmpeg/bin automatically when run from source,
|
||||
and build.py --ffmpeg-dir ffmpeg/bin bundles them with the executable.
|
||||
and build.py --ffmpeg-dir ffmpeg/bin bundles them with the executable, together
|
||||
with the build's license, which is saved as ./ffmpeg/LICENSE.txt.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -52,27 +53,50 @@ def main() -> int:
|
||||
archive = Path(tmp) / asset["name"]
|
||||
with urllib.request.urlopen(asset["browser_download_url"], timeout=60) as r, open(archive, "wb") as f:
|
||||
shutil.copyfileobj(r, f)
|
||||
DEST.mkdir(parents=True, exist_ok=True)
|
||||
wanted = {f"ffmpeg{exe}", f"ffprobe{exe}"}
|
||||
if archive.suffix == ".zip":
|
||||
with zipfile.ZipFile(archive) as z:
|
||||
for info in z.infolist():
|
||||
name = Path(info.filename).name
|
||||
if name in wanted and "/bin/" in info.filename:
|
||||
(DEST / name).write_bytes(z.read(info))
|
||||
else:
|
||||
with tarfile.open(archive) as t:
|
||||
for m in t.getmembers():
|
||||
name = Path(m.name).name
|
||||
if name in wanted and "/bin/" in m.name:
|
||||
with t.extractfile(m) as src, open(DEST / name, "wb") as out:
|
||||
shutil.copyfileobj(src, out)
|
||||
(DEST / name).chmod(0o755)
|
||||
missing = [n for n in wanted if not (DEST / n).is_file()]
|
||||
extract(archive, exe, DEST)
|
||||
print(f"Installed ffmpeg and ffprobe into {DEST}, and their license as {DEST.parent / 'LICENSE.txt'}")
|
||||
return 0
|
||||
|
||||
|
||||
def extract(archive: Path, exe: str, dest: Path) -> None:
|
||||
"""Copy ffmpeg + ffprobe from the archive's bin/ into dest, and its LICENSE.txt into dest's parent.
|
||||
|
||||
A BtbN archive holds one top folder with bin/ and LICENSE.txt in it. ffmpeg is GPL, so the
|
||||
license has to ship with the binaries; build.py picks it up from there.
|
||||
"""
|
||||
dest.mkdir(parents=True, exist_ok=True)
|
||||
license_out = dest.parent / "LICENSE.txt"
|
||||
license_out.unlink(missing_ok=True)
|
||||
wanted = {f"ffmpeg{exe}", f"ffprobe{exe}"}
|
||||
|
||||
def target(member: str) -> Path | None:
|
||||
name = Path(member).name
|
||||
if name in wanted and "/bin/" in member:
|
||||
return dest / name
|
||||
if member.strip("/").count("/") == 1 and name == "LICENSE.txt":
|
||||
return license_out
|
||||
return None
|
||||
|
||||
if archive.suffix == ".zip":
|
||||
with zipfile.ZipFile(archive) as z:
|
||||
for info in z.infolist():
|
||||
out = target(info.filename)
|
||||
if out:
|
||||
out.write_bytes(z.read(info))
|
||||
else:
|
||||
with tarfile.open(archive) as t:
|
||||
for m in t.getmembers():
|
||||
out = target(m.name) if m.isfile() else None
|
||||
if out:
|
||||
with t.extractfile(m) as src, open(out, "wb") as f:
|
||||
shutil.copyfileobj(src, f)
|
||||
if out.name in wanted:
|
||||
out.chmod(0o755)
|
||||
missing = [n for n in sorted(wanted) if not (dest / n).is_file()]
|
||||
if not license_out.is_file():
|
||||
missing.append("LICENSE.txt")
|
||||
if missing:
|
||||
raise SystemExit(f"Archive did not contain {missing}")
|
||||
print(f"Installed ffmpeg and ffprobe into {DEST}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user