SubtitleEdit/subtitleedit · error · InvalidOperationException

Failed to initialize mpv: {player.GetErrorString(err)}

Error message

Failed to initialize mpv: {player.GetErrorString(err)}

What it means

Thrown inside TextToSpeechViewModel.PlayAudio when a freshly constructed LibMpvDynamicPlayer fails Initialize() during an audio preview in the main Text-to-Speech window. The code disposes any previous preview player, then under _playLock builds a new player, LoadLib(), and Initialize(); a negative return is converted to this InvalidOperationException. As written (lines 2215-2235) the throw is not caught locally — it propagates to the command/preview caller. A subsequent close can null _mpvContext out from under the awaited LoadAudio, which is the separate race noted in the comment.

Source

Thrown at src/ui/Features/Video/TextToSpeech/TextToSpeechViewModel.cs:2227

            {
                SeLogger.Error(ex, "TTS window: disposing the audio preview player failed");
            }
        });
    }

    private async Task PlayAudio(string fileName)
    {
        DisposePreviewPlayer();

        LibMpvDynamicPlayer player;
        lock (_playLock)
        {
            player = new LibMpvDynamicPlayer();
            player.LoadLib(); // core not initialized"
            var err = player.Initialize();
            if (err < 0)
            {
                throw new InvalidOperationException($"Failed to initialize mpv: {player.GetErrorString(err)}");
            }

            _mpvContext = player;
        }

        // Through the local: a close running now can null the field out from under us.
        await player.LoadAudio(fileName);
    }

    private async Task<bool> IsEngineInstalled(ITtsEngine engine)
    {
        return await TtsEngineInstaller.EnsureEngineInstalled(engine, Window, _windowService, SelectedRegion, SelectedModel, ApiKey, KeyFile, () => RefreshVoices(engine));
    }

    private async Task MergeAndAddToVideo(TtsStepResult[] fixSpeedResult)
    {
        // Merge audio paragraphs
        var mergedAudioFileName = await MergeAudioParagraphs(fixSpeedResult, _cancellationToken);

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Read the embedded GetErrorString(err) in the exception message for the concrete mpv error.
  2. Confirm libmpv bitness/arch matches the process and install the required C++ runtime.
  3. Re-download the mpv player through SE to replace a corrupt/mismatched libmpv.
  4. Consider guarding LoadLib with CanLoad() and wrapping Initialize in try/catch that resets preview UI state, matching the pattern in ReviewSpeechViewModel.

Example fix

// before
player.LoadLib();
var err = player.Initialize();
if (err < 0) throw new InvalidOperationException($"Failed to initialize mpv: {player.GetErrorString(err)}");

// after - validate load and contain init failures so preview does not strand
player.LoadLib();
if (!player.CanLoad())
    throw new InvalidOperationException("libmpv could not be loaded for audio preview.");
int err;
try { err = player.Initialize(); }
catch (Exception ex) { throw new InvalidOperationException("mpv init threw: " + ex.Message, ex); }
if (err < 0) throw new InvalidOperationException($"Failed to initialize mpv: {player.GetErrorString(err)}");
Defensive patterns

Strategy: try-catch

Validate before calling

player = new LibMpvDynamicPlayer();
if (!player.CanLoad()) throw new InvalidOperationException("libmpv could not be loaded for preview.");

Try / catch

try
{
    lock (_playLock)
    {
        player = new LibMpvDynamicPlayer();
        player.LoadLib();
        var err = player.Initialize();
        if (err < 0) throw new InvalidOperationException($"Failed to initialize mpv: {player.GetErrorString(err)}");
        _mpvContext = player;
    }
    await player.LoadAudio(fileName);
}
catch (Exception ex)
{
    SeLogger.Error(ex, "TTS preview playback failed");
    // reset preview UI state and re-enable controls
}

Prevention

When it happens

Trigger: libmpv present but mpv_initialize returns negative: wrong arch/bitness of libmpv, missing VC++ runtime, corrupt libmpv, or an initialization option rejected by the core.

Common situations: User swapped libmpv for a mismatched build; missing runtime after a fresh Windows install; antivirus damaged libmpv; SE upgraded to a libmpv needing a newer runtime.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/34201f2f568a6d93. Report an issue: GitHub.