Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ Place [this][build] in your mpv `scripts` folder. The `scripts` folder can be fo

Additional details about the folder structure can be found in the [mpv's manual][file locations].

### Encoder executable

Encoding starts a separate `mpv` process. The `mpv` executable must be available on the `PATH` inherited by the player, including when the player is opened from a desktop shortcut or file manager.

- **Windows:** follow the [Windows encoder setup guide](docs/windows-encoder-setup.md) for step-by-step instructions to add mpv to `Path`, verify it, and troubleshoot desktop launches.
- **Linux/macOS:** run `command -v mpv` to check your shell's `PATH`. If encoding reports `mpv: command not found` when launched from the desktop, ensure that launch environment also includes the executable's directory. Homebrew commonly installs it in `/opt/homebrew/bin` on Apple Silicon and `/usr/local/bin` on Intel Macs.

If encoding instead reports a missing codec, check `mpv --ovc=help` for video encoders or `mpv --oac=help` for audio encoders. These lists come from the FFmpeg libraries used by **mpv**; installing a separate `ffmpeg` executable does not necessarily add codecs to mpv. On macOS, the Homebrew formula (`brew install mpv`) is one source of an encoder-enabled build.
Comment thread
ekisu marked this conversation as resolved.

By default, the script is activated by the W (shift+w) key.

## Usage
Expand Down
63 changes: 63 additions & 0 deletions docs/windows-encoder-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Windows encoder setup

mpv-webm starts a second `mpv.exe` to encode your clip. Windows must be able to
find it through the `Path` environment variable, even when you open the player
by double-clicking a video.

## 1. Locate mpv

If needed, get a Windows build from the [mpv installation page](https://mpv.io/installation/).
Extract the archive into a permanent folder, for example `C:\Tools\mpv`.
Check that `mpv.exe` is directly inside that folder. Use your actual folder in
the steps below; do not add the archive or the executable filename to `Path`.

## 2. Add that folder to your user Path

1. Open **Start**, search for **Edit environment variables for your account**,
and open that settings dialog.
2. Under **User variables for your account**, select **Path**, then **Edit**.
3. Click **New** and enter the folder containing `mpv.exe`, for example
`C:\Tools\mpv`. Keep the existing entries. Do not put quotes around the folder.
4. If your account has no `Path` variable yet, click **New** in the User variables
section, use `Path` as the name and the mpv folder as the value.
5. Click **OK** in each dialog to save the change.

## 3. Verify and restart the player

Close existing Command Prompt and mpv windows. Open a **new Command Prompt**
from Start and run:

```bat
where mpv
mpv --version
```

`where mpv` should print the path to your `mpv.exe`, and `mpv --version` should
print version information. If Windows cannot find it, check that the folder
from step 2 really contains `mpv.exe` and that the change was saved.

Open mpv again and try encoding. If a terminal launch works but opening a video
from Explorer still fails, sign out of Windows and sign back in so Explorer
and other launchers inherit the updated environment. Restart third-party
launchers too. File associations alone do not put mpv on `Path`.

If `where mpv` lists multiple copies, Windows normally selects the first one.
Check that it is the build you intended to use.

## 4. If mpv starts but an encoder is missing

Run:

```bat
mpv --ovc=help
mpv --oac=help
```

These list the video and audio encoders in your mpv build. Select a supported
format or install an mpv build with the required codec. Installing a separate
FFmpeg executable does not change the codecs compiled into mpv.

The message **Cannot start the mpv encoder** points to an executable startup
problem; the message **mpv encoder failed its startup check** means mpv was
launched but returned an error. Run `mpv --version` and inspect the player logs
for the underlying diagnostic.
17 changes: 17 additions & 0 deletions src/encode.moon
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,25 @@ find_path = (startTime, endTime) ->

return path, is_stream, is_temporary, startTime, endTime

-- Probe the same executable before entering any launch mode (including the
-- progress shell and detached mode, which otherwise hide spawn failures).
check_encoder = ->
result = utils.subprocess({args: {"mpv", "--no-config", "--version"}, cancellable: false})
if result.status == 0
return true
explanation = "Cannot start the mpv encoder. Add the folder containing mpv to PATH, then restart the player. See README: Encoder executable."
if result.status and result.status > 0
explanation = "The mpv encoder failed its startup check. Run mpv --version and check the logs for details."
msg.error(explanation)
msg.error("Encoder startup check: ", result.error or "", result.stderr or "", result.stdout or "")
message(explanation, 10)
emit_event("encode-finished", "fail", explanation)
return false

encode = (region, startTime, endTime) ->
format = formats[options.output_format]
if not check_encoder!
return

originalStartTime = startTime
originalEndTime = endTime
Expand Down
3 changes: 2 additions & 1 deletion tests/testcases/base_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

class BaseTestCase(unittest.TestCase):
# GUI subclasses supply a real video output and an isolated DISPLAY.
mpv_executable = "mpv"
mpv_args = ()
mpv_env = None

Expand All @@ -31,7 +32,7 @@ def setUp(self):
self.log_reader = None
socket_address = str(self.tempdir / "ipc")
args = [
"mpv", "-v", "--no-config", "--vo=null", "--ao=null",
self.mpv_executable, "-v", "--no-config", "--vo=null", "--ao=null",
"--load-scripts=no", "--scripts-clr", "--idle=yes",
"--input-ipc-server=" + socket_address,
*self.mpv_args,
Expand Down
34 changes: 34 additions & 0 deletions tests/testcases/test_encoder_startup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os
import shutil
import tempfile

from .base_test_case import BaseTestCase, ROOT


class TestMissingEncoder(BaseTestCase):
def setUp(self):
# Start a real player by absolute path, but make its child mpv lookup
# fail. This reproduces a desktop launch with an incomplete PATH.
self.mpv_executable = shutil.which("mpv")
self.assertIsNotNone(self.mpv_executable)
empty_path = tempfile.TemporaryDirectory(prefix="mpv-empty-path-")
self.addCleanup(empty_path.cleanup)
self.mpv_env = {**os.environ, "PATH": empty_path.name}
super().setUp()

def test_missing_encoder_reports_actionable_error_in_all_launch_modes(self):
self.openTestVideoFile(ROOT / "tests/videos/big_buck_bunny_10s.mp4")
self.setRange(0, 1)
for mode in ({"display_progress": False, "run_detached": False, "twopass": False},
{"display_progress": True, "run_detached": False, "twopass": False},
{"display_progress": False, "run_detached": True, "twopass": False},
{"display_progress": False, "run_detached": False, "twopass": True}):
with self.subTest(mode=mode):
self.updateScriptOptions({**mode, "output_template": "missing"})
event = self.scriptMessage("mpv-webm-encode", event="webm-encode-finished")
self.assertEqual(event.args[:2], ["webm-encode-finished", "fail"])
self.assertIn("Cannot start the mpv encoder", event.args[2])
self.assertIn("PATH", event.args[2])
self.assertIn("restart the player", event.args[2])
self.waitUntil(lambda: event.args[2] in self.getLog(), "actionable encoder error log")
self.assertFalse((self.tempdir / "missing.webm").exists())
Loading