Repository navigation
Fix Mixkit stock adapter; add keyless mixkit_music tool; configurable atelier render timeout - #801
Conversation
… atelier timeout - stock_sources/mixkit: match current `.item-grid-card` markup and download the direct 1080p asset by video id (720p fallback); the old selectors returned zero results. - audio/mixkit_music: keyless music search/download from Mixkit's schema.org JSON-LD (Mixkit Stock Music Free License); fallback when Pixabay 403s. - audio/gemini_tts: Gemini API speech generation with natural-language style prompts (GEMINI_API_KEY / GOOGLE_API_KEY, google-genai SDK). - video_compose: atelier render honours optional bespoke.timeout_seconds (default unchanged at 1800s) for long renders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tools/mixkit-gemini-tts-compose-timeout # Conflicts: # tests/contracts/test_phase3_contracts.py # tools/audio/gemini_tts.py
calesthio
left a comment
There was a problem hiding this comment.
Thank you for the sourcing repair and configurable atelier timeout. The 35 stock-source adapter tests pass (three existing xfails), but the new direct download path needs two corrections.
[P1] Resolve the clip's actual license before downloading a guessed rendition. tools/video/stock_sources/mixkit.py constructs an ID-based 1080 URL and, on any failure, downloads the 720 variant without checking the detail page. Every candidate is still labelled free for commercial use. Mixkit has both Free and Restricted video licenses: for example clip31544 explicitly offers its free 720p file for personal use only. A mocked listing/download reproduction takes exactly that fallback while retaining the commercial-use label. Resolve the published file/rendition and per-item license, preserve the license evidence, and exclude restricted assets when commercial use is required. Add both license variants and failed-1080 cases to the adapter tests.
[P2] Keep music download failures inside ToolResult. MixkitMusic.execute catches search errors, but the subsequent urlopen/read/write at tools/audio/mixkit_music.py:104 is outside the try block. A normal CDN/network error escapes the tool instead of returning a failed result; I reproduced this with a mocked URLError. Catch download/filesystem errors and add list/download/failure/registry coverage plus provider setup/license documentation. The music license also has distribution limits that should accompany its broad commercial-use description.
No real media was downloaded or generation called.
Addresses review on OpenMontageInc#801. P1 - stock_sources/mixkit: - Mixkit publishes video under two licences per clip: Stock Video Free (commercial OK) and Stock Video Restricted (free 720p for personal use only; YouTube, ads and commercial projects not allowed). - search() now labels each candidate with the licence the listing page's schema.org data declares and, by default, drops Restricted clips (new SearchFilters.require_commercial_use, default True; other sources may ignore it). Candidates no longer carry a guessed file URL. - download() reads the clip's detail page (authoritative), refuses Restricted clips when commercial use is required (MixkitLicenseError), and downloads only renditions the page publishes via its download modal, best first; a failed 1080p falls back to the page's own 720p link, never a guessed URL. The verified licence and evidence (key, rendition, file URL, detail URL, timestamp) are written to Candidate.license / extra["license_evidence"]. P2 - audio/mixkit_music: - Download/filesystem errors return a failed ToolResult (partial file removed) instead of escaping the tool. - Documents the Stock Music Free License limits (no CDs/DVDs, broadcast, video games, remixes or Content ID registration) in the module, install_instructions, not_good_for and on every returned track. - Both tools: accept ld+json script tags with extra attributes. Docs: Mixkit section in docs/PROVIDERS.md (setup + licence table). Tests: tests/tools/test_mixkit_source.py (both licence variants, default exclusion, failed-1080 fallback, all-renditions-fail, no-licence page) and tests/tools/test_mixkit_music.py (list, download, URLError, search failure, pick range, registry). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the conflict in tools/video/stock_sources/mixkit.py by keeping both intents: upstream's JSON-LD resolution (contentUrl at download, the JSON-LD search fallback, declared width/height) and this branch's per-clip licence verification. JSON-LD contentUrl and the <video> source are now fallbacks after the page's published download renditions, and every path requires a stated licence when commercial use is required. Upstream tests keep their coverage; their fixtures now state a licence, and the JSON-LD search fallback points candidates at the detail page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for the careful review — both points were right, and the P1 one was worse than it looked: when I re-checked against live pages, most Mixkit clips I'd pulled for a real project are published under the Restricted licence (free 720p for personal use only; YouTube/commercial explicitly not allowed). Pushed in [P1] Per-clip licence, published renditions only —
[P2] Music —
Docs: Mixkit section in Tests
|
Summary
Fixes and small additions found while producing a 20-minute narrated explainer end-to-end with the
hybridpipeline (Remotion atelier, keyless stock only):pixabay_musicgets HTTP 403 from Pixabay, which left no working keyless music source.timeout=1800invideo_compose.(An earlier revision of this PR also added a
gemini_ttstool.mainhas since gained its own, more completegemini_tts, so the merge takesmain's version and this PR no longer touches it.)Related issue
None filed — happy to open one if preferred.
Changes
tools/video/stock_sources/mixkit.py:.item-grid-cardcard markup.assets.mixkit.co/videos/<id>/<id>-1080.mp4file by id, with a-720.mp4fallback.tools/audio/mixkit_music.py(new;capability="music_search"; no API key):pick+output_path.tools/video/video_compose.py: the atelier render reads an optionalbespoke.timeout_seconds. The default stays 1800 s, so existing callers are unchanged.Testing
pytest tests/contracts/on the merged branch gives 1241 passed, 7 skipped.test_phase2_contracts.py::TestPhase2ErrorHandling::test_image_selector_no_provider.tools/graphics/local_diffusion.py(torch) on my machine, and also does so onmainwithout this change. It's an environment issue unrelated to this PR.search("tomato")now returns 20 candidates (it returned 0 before). About 40 clips downloaded through the adapter.mixkit_music: searchedcomedy,cartoonsandquirky, downloaded 5 tracks, and used them in a rendered video.bespoke.timeout_seconds=5400, andfinal_reviewpassed.Checklist
pytest tests/contracts/) where applicable.install_instructions/best_for.Notes for reviewers
mixkit_musicis EXPERIMENTAL, likepixabay_music, because it depends on the JSON-LD that Mixkit embeds in its pages.🤖 Generated with Claude Code