Jump to content

Emby Theater Desktop Playback of 3D Movie Remuxes (mk3d or mkv Containers) Freezes After ~26 Minutes


shpitz461

Recommended Posts

Guest asrequested

It just means playback ended. it could also have ended naturally by the player.

 

Yeah, the log doesn't show anything for when it stops, only for when I press stop. 

Link to comment
Share on other sites

Guest asrequested

OK, this is as far as I've gotten, and it makes no difference.

var processes = {};
var timeposition = 0;
var mainWindowRef
var mpv = require('node-mpv');
var mpvPlayer;
var playerWindowId;
var mpvPath;
var playMediaSource;
var playMediaType;
var playerStatus;
var fadeTimeout;
var currentVolume;
var currentPlayResolve;
var currentPlayReject;

function alert(text) {
    require('electron').dialog.showMessageBox(mainWindowRef, {
        message: text.toString(),
        buttons: ['ok']
    });
}

function play(player, path) {
    return new Promise(function (resolve, reject) {
        console.log('Play URL : ' + path);
        currentPlayResolve = resolve;
        currentPlayReject = reject;

        if (path.toLowerCase('http').indexOf() != -1) {
            //player.loadStream(path);
            player.loadFile(path);
        } else {
            player.loadFile(path);
        }
    });
}

function stop() {
    mpvPlayer.stop();
}

function pause() {
    mpvPlayer.pause();
}

function pause_toggle() {
    mpvPlayer.togglePause();
}

function unpause() {
    mpvPlayer.resume();
}

function set_position(data) {
    mpvPlayer.goToPosition(Math.round(data / 10000000));
}

function setAspectRatio(player, value) {

    switch (value) {
        case "4_3":
            player.setProperty("video-unscaled", "no");
            player.setProperty("video-aspect", "4:3");
            break;
        case "16_9":
            player.setProperty("video-unscaled", "no");
            player.setProperty("video-aspect", "16:9");
            break;
        case "bestfit":
            player.setProperty("video-unscaled", "no");
            player.setProperty("video-aspect", "-1");
            break;
        case "fill":
            //var size = player.getProperty("android-surface-size");
            //var aspect = parseFloat(size.split("x")[0]) / parseFloat(size.split("x")[1]);
            //player.setProperty("video-unscaled", "no");
            //player.setProperty("video-aspect", aspect);

            break;
        case "original":
            player.setProperty("video-unscaled", "downscale-big");
            player.setProperty("video-aspect", "-1");
            break;
    }
}

function set_volume(data) {
    mpvPlayer.volume(data);
}

function mute() {
    mpvPlayer.mute();
}

function unmute() {
    mpvPlayer.unmute();
}

function set_audiostream(player, index) {

    var audioIndex = 0;
    var i, length, stream;
    var streams = playMediaSource.MediaStreams || [];
    for (i = 0, length = streams.length; i < length; i++) {
        stream = streams[i];
        if (stream.Type == 'Audio') {
            audioIndex++;
            if (stream.Index == index) {
                break;
            }
        }
    }
    player.setProperty("aid", audioIndex);
}

function set_subtitlestream(player, index) {

    if (index < 0) {
        player.setProperty("sid", "no");
    } else {
        var subIndex = 0;
        var i, length, stream;
        var streams = playMediaSource.MediaStreams || [];
        for (i = 0, length = streams.length; i < length; i++) {
            stream = streams[i];
            if (stream.Type == 'Subtitle') {
                subIndex++;

                if (stream.Index == index) {
                    if (stream.DeliveryMethod == 'External') {

                        player.addSubtitles(stream.DeliveryUrl, "cached", stream.DisplayTitle, stream.Language);
                    } else {
                        player.setProperty("sid", subIndex);
                    }

                    break;
                }
            }
        }
    }
}

function getMpvOptions(options, mediaType, mediaSource) {

    var list = [];

    if (options.openglhq) {
        list.push('mpv.conf');
    
    }

    list.push('mpv.conf');

    if (options.deinterlace == 'yes') {
        list.push('mpv.conf');
    }

    list.push('mpv.conf');

    if (options.videoSync) {

        list.push('mpv.conf');
    }

    if (options.scale) {

        list.push('mpv.conf');
    }

    if (options.cscale) {

        list.push('mpv.conf');
    }

    if (options.dscale) {

        list.push('mpv.conf');
    }

    if (options.interpolation) {

        list.push('mpv.conf');

        if (options.tscale) {

            list.push('mpv.conf');
        }
    }

    if (options.correctdownscaling) {

        list.push('mpv.conf');
    }

    if (options.sigmoidupscaling) {

        list.push('mpv.conf');
    }

    if (options.deband) {

        list.push('mpv.conf');
    }

    if (options.ditherdepth) {

        list.push('mpv.conf');
    }

    if (options.videoStereoMode) {

        list.push('mpv.conf');
    }

    if (options.subtitleFontFamily) {

        list.push('mpv.conf');
    }

    if (options.subtitleFontSize) {

        list.push('mpv.conf');
    }

    var audioOptions = getMpvAudioOptions(options, mediaType);
    for (var i = 0, length = audioOptions.length; i < length; i++) {
        list.push(audioOptions[i]);
    }

    var videoStream = (mediaSource.MediaStreams || []).filter(function (v) {
        return v.Type == 'Video';
    })[0];

    var framerate = videoStream ? (videoStream.AverageFrameRate || videoStream.RealFrameRate) : 0;

    var audioDelay = framerate >= 23 && framerate <= 25 ? options.audioDelay2325 : options.audioDelay;
    if (audioDelay) {
        list.push('mpv.conf');
    }

    if (options.genPts) {

        list.push('mpv.conf');
    }
	
    return list;
}

function getMpvAudioOptions(options, mediaType) {

    var list = [];

    var audioChannels = options.audioChannels || 'auto-safe';
    var audioFilters = [];
    if (audioChannels === '5.1') {
        audioChannels = '5.1,stereo';
    }
    else if (audioChannels === '7.1') {
        audioChannels = '7.1,stereo';
    }

    var audioChannelsFilter = getAudioChannelsFilter(options, mediaType);
    if (audioChannelsFilter) {
        audioFilters.push(audioChannelsFilter);
    }

    if (audioFilters.length) {

        list.push('--af=lavfi=[' + (audioFilters.join(',')) + ']');
    }

    list.push('--audio-channels=' + (audioChannels));

    if (options.audioSpdif) {
        list.push('--audio-spdif=' + (options.audioSpdif));
    }

    list.push('--ad-lavc-ac3drc=' + (options.dynamicRangeCompression || 0));

    if (options.exclusiveAudio && mediaType === 'Video') {
        list.push('--audio-exclusive=yes');
    }

    return list;
}

function getAudioChannelsFilter(options, mediaType) {

    var enableFilter = false;
    var upmixFor = (options.upmixAudioFor || '').split(',');

    if (mediaType === 'Audio') {
        if (upmixFor.indexOf('music') !== -1) {
            enableFilter = true;
        }
    }

    //there's also a surround filter but haven't found good documentation to implement -PMR 20171225
    if (enableFilter) {
        var audioChannels = options.audioChannels || '';
        if (audioChannels === '5.1') {
            //return 'channels=6';
            return 'pan=5.1|FL=FL|BL=FL|FR=FR|BR=FR|FC<0.5*FL + 0.5*FR';
        }
        else if (audioChannels === '7.1') {
            //return 'channels=8';
            return 'pan=7.1|FL=FL|SL=FL|BL=FL|FR=FR|SR=FR|BR=FR|FC<0.5*FL + 0.5*FR';
        }
    }

    return '';
}

function fade(startingVolume) {
    var newVolume = Math.max(0, startingVolume - 0.15);
    set_volume(newVolume);

    if (newVolume <= 0) {
        return Promise.resolve();
    }

    return new Promise(function (resolve, reject) {

        cancelFadeTimeout();

        fadeTimeout = setTimeout(function () {
            fade(newVolume).then(resolve, reject);
        }, 1);
    });
}

function cancelFadeTimeout() {
    var timeout = fadeTimeout;
    if (timeout) {
        clearTimeout(timeout);
        fadeTimeout = null;
    }
}

function cleanup() {

    var player = mpvPlayer;

    player.removeAllListeners('timeposition');
    player.removeAllListeners('started');
    player.removeAllListeners('statuschange');
    player.removeAllListeners('stopped');

    try {
        player.quit();
    }
    catch (err) {
        console.log('error quitting mpv: ' + err);
    }

    delete mpvPlayer;

    mpvPlayer = null;
    playMediaSource = null;
    playMediaType = null;
    playerStatus = null;
}

function getReturnJson(positionTicks) {
    var playState = "playing";
    if (playerStatus.pause) {
        playState = "paused";
    }

    if (playerStatus['idle-active']) {
        playState = "idle";
    }

    var state = {
        isPaused: playerStatus.pause || false,
        isMuted: playerStatus.mute || false,
        volume: currentVolume || playerStatus.volume || 100,
        positionTicks: positionTicks || timeposition,
        playstate: playState,
        demuxerCacheState: playerStatus['demuxer-cache-state']
    }

    if (playerStatus.duration) {

        state.durationTicks = playerStatus.duration * 10000000;
    } else if (playerStatus['demuxer-cache-time']) {
        state.durationTicks = playerStatus['demuxer-cache-time'] * 10000000;
    }

    return Promise.resolve(JSON.stringify(state));
}

function getAudioStats(player) {

    var properties = [
        { property: 'audio-codec-name' },
        { property: 'audio-out-params' },
        { property: 'audio-bitrate', name: 'Audio bitrate:', type: 'bitrate' },
        { property: 'current-ao', name: 'Audio renderer:' },
        { property: 'audio-out-detected-device', name: 'Audio output device:' }
    ];

    var promises = properties.map(function (p) {
        return player.getProperty(p.property);
    });

    return Promise.all(promises).then(function (responses) {

        var stats = [];

        if (responses[0]) {
            stats.push({
                label: 'Audio codec:',
                value: responses[0]
            });
        }

        var audioParams = responses[1] || {};

        if (audioParams.channels) {
            stats.push({
                label: 'Audio channels:',
                value: audioParams.channels
            });
        }
        if (audioParams.samplerate) {
            stats.push({
                label: 'Audio sample rate:',
                value: audioParams.samplerate
            });
        }

        for (var i = 2, length = properties.length; i < length; i++) {

            var name = properties[i].name;

            var value = responses[i];

            if (properties[i].type == 'bitrate') {
                value = getDisplayBitrate(value);
            }

            if (value != null) {
                stats.push({
                    label: name,
                    value: value
                });
            }
        }
        return {
            stats: stats,
            type: 'audio'
        };
    });
}

function getDisplayBitrate(bitrate) {

    if (bitrate > 1000000) {
        return (bitrate / 1000000).toFixed(1) + ' Mbps';
    } else {
        return Math.floor(bitrate / 1000) + ' kbps';
    }
}

function getDroppedFrames(responses) {

    var html = '';

    html += (responses[responses.length - 4] || '0');

    html += ', Decoder dropped: ' + (responses[responses.length - 3] || '0');

    html += ', Mistimed: ' + (responses[responses.length - 2] || '0');

    html += ', Delayed: ' + (responses[responses.length - 1] || '0');

    return html;
}

function getVideoStats(player) {

    var properties = [
        { property: 'video-out-params' },
        { property: 'video-codec', name: 'Video codec:' },
        { property: 'video-bitrate', name: 'Video bitrate:', type: 'bitrate' },
        { property: 'current-vo', name: 'Video renderer:' },
        { property: 'hwdec-current', name: 'Hardware acceleration:' },
        { property: 'display-names', name: 'Display devices:' },
        { property: 'display-fps', name: 'Display fps:' },
        { property: 'estimated-display-fps', name: 'Estimated display fps:' },
        { property: 'display-sync-active', name: 'Display sync active:' },
        { property: 'frame-drop-count' },
        { property: 'decoder-frame-drop-count' },
        { property: 'mistimed-drop-count' },
        { property: 'vo-delayed-frame-count' }
    ];

    var promises = properties.map(function (p) {
        return player.getProperty(p.property);
    });

    return Promise.all(promises).then(function (responses) {

        var stats = [];

        var videoParams = responses[0] || {};

        for (var i = 1, length = properties.length - 4; i < length; i++) {

            var name = properties[i].name;

            var value = responses[i];

            if (properties[i].type == 'bitrate') {
                value = getDisplayBitrate(value);
            }

            if (value != null) {
                stats.push({
                    label: name,
                    value: value
                });
            }
        }

        stats.push({
            label: 'Dropped frames:',
            value: getDroppedFrames(responses)
        });

        var winPosition = mainWindowRef.getPosition();
        var displayParams = require('electron').screen.getDisplayNearestPoint({ x: winPosition[0], y: winPosition[1] })

        stats.push({
            label: 'Display Fullscreen Resolution:',
            value: displayParams.size.width + ' x ' + displayParams.size.height
        });

        if (videoParams.w && videoParams.h) {
            stats.push({
                label: 'Video resolution:',
                value: videoParams.w + ' x ' + videoParams.h
            });
        }

        if (videoParams.aspect) {
            stats.push({
                label: 'Aspect ratio:',
                value: videoParams.aspect
            });
        }

        if (videoParams.pixelformat) {
            stats.push({
                label: 'Pixel format:',
                value: videoParams.pixelformat
            });
        }

        if (videoParams.colormatrix) {
            stats.push({
                label: 'Color matrix:',
                value: videoParams.colormatrix
            });
        }

        if (videoParams.primaries) {
            stats.push({
                label: 'Primaries:',
                value: videoParams.primaries
            });
        }

        if (videoParams.gamma) {
            stats.push({
                label: 'Gamma:',
                value: videoParams.gamma
            });
        }

        if (videoParams.colorlevels) {
            stats.push({
                label: 'Levels:',
                value: videoParams.colorlevels
            });
        }

        return {
            stats: stats,
            type: 'video'
        };
    });
}

function getMediaStats(player) {

    var properties = [
        { property: 'media-title', name: 'Title:' },
        { property: 'chapter', name: 'Chapter:' }
    ];

    var promises = properties.map(function (p) {
        return player.getProperty(p.property);
    });

    return Promise.all(promises).then(function (responses) {

        var stats = [];

        for (var i = 0, length = properties.length; i < length; i++) {

            var name = properties[i].name;

            var value = responses[i];

            if (value != null) {
                stats.push({
                    label: name,
                    value: value
                });
            }
        }
        return {
            stats: stats,
            type: 'media'
        };
    });
}

function getStatsJson(player) {

    return Promise.all([getMediaStats(player), getVideoStats(player), getAudioStats(player)]).then(function (responses) {

        var categories = [];

        for (var i = 0, length = responses.length; i < length; i++) {
            categories.push(responses[i]);
        }

        return JSON.stringify({
            categories: categories
        });
    });
}

function processRequest(request, body) {
    return new Promise(function (resolve, reject) {
        var url = require('url');
        var url_parts = url.parse(request.url, true);
        var action = url_parts.pathname.substring(1).toLowerCase();

        switch (action) {

            case 'play':
                var data = JSON.parse(body);
                playMediaSource = data.mediaSource;
                createMpv(data.playerOptions, data.mediaType, playMediaSource);
                playMediaType = data.mediaType;

                var startPositionTicks = data["startPositionTicks"];

                mpvPlayer.volume(data.playerOptions.volume || 100);

                play(mpvPlayer, data.path).then(() => {
                    if (playMediaSource.DefaultAudioStreamIndex != null && data.playMethod != 'Transcode') {
                        set_audiostream(mpvPlayer, playMediaSource.DefaultAudioStreamIndex);
                    }

                    if (playMediaSource.DefaultSubtitleStreamIndex != null) {
                        set_subtitlestream(mpvPlayer, playMediaSource.DefaultSubtitleStreamIndex);
                    }
                    else {
                        set_subtitlestream(mpvPlayer, -1);
                    }

                    if (startPositionTicks != 0) {
                        set_position(startPositionTicks);
                    }

                    getReturnJson(startPositionTicks).then(resolve);
                }).catch(reject);

                break;
            case 'stats':
                if (mpvPlayer) {
                    getStatsJson(mpvPlayer).then(resolve);
                } else {
                    resolve('[]');
                }
                break;
            case 'stop':
                stop();
                getReturnJson().then(resolve);
                break;
            case 'stopdestroy':

                getReturnJson().then(function (returnJson) {
                    if (playMediaType.toLowerCase() === 'audio') {
                        currentVolume = playerStatus.volume || 100;
                        fade(currentVolume).then(() => {
                            stop();
                            set_volume(currentVolume);
                            currentVolume = null;
                            cleanup();
                        }).catch(reject);
                    } else {
                        stop();
                        cleanup();
                    }

                    resolve(returnJson);
                });

                break;
            case 'positionticks':
                var data = url_parts.query["val"];
                set_position(data);
                timeposition = data;
                getReturnJson().then(resolve);
                break;
            case 'seekrelative':
                var data = url_parts.query["val"];
                mpvPlayer.seek(Math.round(data / 10000000));
                //timeposition = (timeposition || 0) + data;
                getReturnJson().then(resolve);
                break;
            case 'unpause':
                unpause();
                getReturnJson().then(resolve);
                break;
            case 'playpause':
                pause_toggle();
                getReturnJson().then(resolve);
                break;
            case 'pause':
                pause();
                getReturnJson().then(resolve);
                break;
            case 'volumeup':
                set_volume(Math.min(100, (currentVolume || playerStatus.volume || 100) + 2));
                getReturnJson().then(resolve);
                break;
            case 'volumedown':
                set_volume(Math.max(0, (currentVolume || playerStatus.volume || 100) - 2));
                getReturnJson().then(resolve);
                break;
            case 'volume':
                var data = url_parts.query["val"];
                set_volume(data);
                getReturnJson().then(resolve);
                break;
            case 'aspectratio':
                var data = url_parts.query["val"];
                setAspectRatio(mpvPlayer, data);
                getReturnJson().then(resolve);
                break;
            case 'mute':
                mute();
                getReturnJson().then(resolve);
                break;
            case 'unmute':
                unmute();
                getReturnJson().then(resolve);
                break;
            case 'setaudiostreamindex':
                var data = url_parts.query["index"];
                set_audiostream(mpvPlayer, data);
                getReturnJson().then(resolve);
                break;
            case 'setsubtitlestreamindex':
                var data = url_parts.query["index"];
                set_subtitlestream(mpvPlayer, data);
                getReturnJson().then(resolve);
                break;
            case 'video_toggle':
                video_toggle();
                getReturnJson().then(resolve);
                break;
            default:
                // This could be a refresh, e.g. player polling for data
                getReturnJson().then(resolve);
                break;
        }
    });
}

function initialize(playerWindowIdString, mpvBinaryPath) {
    playerWindowId = playerWindowIdString;
    mpvPath = mpvBinaryPath;
}

function onMpvTimePosition(data) {
    timeposition = data * 10000000;
}

function onMpvStarted() {
    var resolve = currentPlayResolve;
    if (resolve) {
        currentPlayResolve = null;
        currentPlayReject = null;
        resolve();
    }
    mainWindowRef.focus();
}

function onMpvStatusChange(status) {
    playerStatus = status;
}

function onMpvStopped() {
    timeposition = 0;
}

function onMpvError() {
    onMpvStopped();
    cleanup();
}

function createMpv(options, mediaType, mediaSource) {
    if (mpvPlayer) return;
    var isWindows = require('is-windows');

    var mpvOptions = getMpvOptions(options, mediaType, mediaSource);

    mpvOptions.push('--wid=' + playerWindowId);
    mpvOptions.push('--no-osc');

    var mpvInitOptions = {
        "debug": false
    };

    if (mpvPath) {
        mpvInitOptions.binary = mpvPath;
    }

    if (isWindows()) {

        mpvInitOptions.socket = "\\\\.\\pipe\\emby-pipe";
        mpvInitOptions.ipc_command = "--input-ipc-server";
    } else {

        mpvInitOptions.socket = "/tmp/emby.sock";
        mpvInitOptions.ipc_command = "--input-unix-socket";
    }

    mpvPlayer = new mpv(mpvInitOptions, mpvOptions);

    mpvPlayer.observeProperty('idle-active', 13);
    mpvPlayer.observeProperty('demuxer-cache-time', 14);
    mpvPlayer.observeProperty('demuxer-cache-state', 15);

    mpvPlayer.on('timeposition', onMpvTimePosition);
    mpvPlayer.on('started', onMpvStarted);
    mpvPlayer.on('statuschange', onMpvStatusChange);
    mpvPlayer.on('stopped', onMpvStopped);
    mpvPlayer.on('error', onMpvError);
}

function processNodeRequest(req, res) {

    var body = [];

    req.on('data', function (chunk) {
        body.push(chunk);
    }).on('end', function () {

        body = Buffer.concat(body).toString();
        // at this point, `body` has the entire request body stored in it as a string

        processRequest(req, body).then((json) => {
            if (json != null) {
                res.writeHead(200, { 'Content-Type': 'application/json' });
                res.end(json);
            } else {
                res.writeHead(500);
                res.end();
            }
        }).catch(() => {
            res.writeHead(500);
            res.end();
        });
    });
}

function registerMediaPlayerProtocol(protocol, mainWindow) {

    mainWindowRef = mainWindow;

    var http = require('http');

    http.createServer(processNodeRequest).listen(8023, '127.0.0.1');
}

exports.initialize = initialize;
exports.registerMediaPlayerProtocol = registerMediaPlayerProtocol;

Link to comment
Share on other sites

shpitz461

Thanks Doofus for your efforts. If there's anything I can provide to help with troubleshooting please let me know.

 

I'm running an i5-4250U in a NUC htpc.

Link to comment
Share on other sites

Guest asrequested

At this point, I don't know what else to do. I've hacked the stuffing out of the handler, and it isn't making a difference. The way Theater is operating obviously doing something that it shouldn't. I still can't figure out why cuda-copy gets around this issue. I was thinking it was something to do with how the gpu-api interacts with electron. But nothing I've tried, changes anything to do with this. What I haven't tried, is altering the audio options. I wouldn't think that has a part in this, but it might. It isn't an mpv issue, as I've retested with the standalone, and it plays without issue. Maybe I'll rip out the audio options, and see what happens.

Link to comment
Share on other sites

shpitz461

I wonder if it's in the way the data is 'transported' or streamed, between playing it directly in MPV via a UNC path and playing via Emby Theatre.

Link to comment
Share on other sites

Guest asrequested

I wonder if it's in the way the data is 'transported' or streamed, between playing it directly in MPV via a UNC path and playing via Emby Theatre.

 

I doubt it, but you can test it just by dragging a movie onto mpv, from a networked location.

Link to comment
Share on other sites

Guest asrequested

Luke, what does this do? Wherever possible, it's better not to apply any filters.  

    var videoStream = (mediaSource.MediaStreams || []).filter(function (v) {
        return v.Type == 'Video';
    })[0];
Edited by Doofus
Link to comment
Share on other sites

shpitz461

I doubt it, but you can test it just by dragging a movie onto mpv, from a networked location.

 

I did when we did our last round of testing a while back, it plays fine. The big difference between internal and external playback is the internal is streaming using a pipe/ipc or something, can't remember the exact term, which apparently causes 3D streams to cause the freeze after so many errors that accumulate over time.

 

It seems that this type of streaming, when the container has the 2nd video stream for 3D effect, causes it to go out of whack. I tried renaming from .mk3d to .mkv and it still freezes after 26 minutes, so it's not the container but the content. I wonder if we remux the streams into an .mp4 container the issue will go away...

 

I also wonder if we use a different splitter (which one is being used? LAV splitter?) the problem will go away...

 

Thoughts?

Link to comment
Share on other sites

Guest asrequested

Have you tried using a different player as an external player? Not as a standalone. That would test your theaory of how it's being served.

 

The MPV logs don't have any errors. As standalone or in theater, they are the same.

Link to comment
Share on other sites

shpitz461

Yes, tried MPC-HC as external, worked like a charm, no freezing every 26 minutes.

 

The MPV log did show errors that accumulate over time until the final freeze after 26 minutes, I should have that log attached to a previous post in this thread.

 

I just looked for a log on my NUC that I generated a while ago, this is where it craps out:

[   2.989][v][cplayer] first video frame after restart shown
[   3.003][v][cplayer] starting audio playback
[   3.004][d][ao/wasapi] Thread Resume
[   3.005][d][ao/wasapi] Thread Reset
[   3.005][v][cplayer] playback restart complete
[   3.016][i][cplayer] Track switched:
[   3.016][i][cplayer]  (+) Video --vid=1 (*) (h264 1920x1080 23.976fps)
[   3.016][i][cplayer]  (+) Audio --aid=1 --alang=eng (*) (dts 8ch 48000Hz)
[   3.016][i][cplayer]      Subs  --sid=1 --slang=eng (hdmv_pgs_subtitle)
[   3.016][i][cplayer]      Subs  --sid=2 --slang=eng (hdmv_pgs_subtitle)
[   3.017][i][cplayer]      Subs  --sid=3 --slang=fra (hdmv_pgs_subtitle)
[   3.017][i][cplayer]      Subs  --sid=4 --slang=spa (hdmv_pgs_subtitle)
[   3.017][i][cplayer]      Subs  --sid=5 --slang=fra (hdmv_pgs_subtitle)
[   3.017][i][cplayer]      Subs  --sid=6 --slang=spa (hdmv_pgs_subtitle)
[   3.017][v][cplayer] Set property: aid=1 -> 1
[   3.028][i][cplayer] Track switched:
[   3.028][i][cplayer]  (+) Video --vid=1 (*) (h264 1920x1080 23.976fps)
[   3.028][i][cplayer]  (+) Audio --aid=1 --alang=eng (*) (dts 8ch 48000Hz)
[   3.028][i][cplayer]      Subs  --sid=1 --slang=eng (hdmv_pgs_subtitle)
[   3.028][i][cplayer]      Subs  --sid=2 --slang=eng (hdmv_pgs_subtitle)
[   3.028][i][cplayer]      Subs  --sid=3 --slang=fra (hdmv_pgs_subtitle)
[   3.028][i][cplayer]      Subs  --sid=4 --slang=spa (hdmv_pgs_subtitle)
[   3.028][i][cplayer]      Subs  --sid=5 --slang=fra (hdmv_pgs_subtitle)
[   3.028][i][cplayer]      Subs  --sid=6 --slang=spa (hdmv_pgs_subtitle)
[   3.028][v][cplayer] Set property: sid="no" -> 1
[   3.799][e][ffmpeg/video] h264: sps_id 1 out of range
[   4.799][e][ffmpeg/video] h264: sps_id 1 out of range
[   5.800][e][ffmpeg/video] h264: sps_id 1 out of range
[   6.801][e][ffmpeg/video] h264: sps_id 1 out of range
[   7.803][e][ffmpeg/video] h264: sps_id 1 out of range
[   8.803][e][ffmpeg/video] h264: sps_id 1 out of range
[   9.804][e][ffmpeg/video] h264: sps_id 1 out of range
[  10.805][e][ffmpeg/video] h264: sps_id 1 out of range
[  11.806][e][ffmpeg/video] h264: sps_id 1 out of range
[  12.807][e][ffmpeg/video] h264: sps_id 1 out of range
[  13.808][e][ffmpeg/video] h264: sps_id 1 out of range
[  14.807][e][ffmpeg/video] h264: sps_id 1 out of range 

This is using internal MPV playback which freezes.

 

i'm generating new logs right now, 1st playing Kung Fu Panda 3 using internal player.

 

i'll report back with both internal and external player logs.

Link to comment
Share on other sites

shpitz461

Attached logs from both internal and external playback, both are using same file from same UNC path.

 

The external playback was stopped at the credits at the end of the movie (~1:29:00 hours), the internal playback has frozen at 00:26:26 hours and I stopped it a while after it froze.

 

Anything these logs show? I'm at work and will examine them tonight.

Panda3_MPV_Logs_internal_vs_external.7z

Edited by shpitz461
Link to comment
Share on other sites

Guest asrequested

The one that played in the external player is as you'd expect. It just finished

[5375.567][d][cplayer] Run command: quit, flags=9, args=[0]
[5375.567][v][cplayer] EOF code: 5  
[5375.567][v][ad] Uninit decoder.
[5375.567][d][ao/wasapi] Thread Reset
[5375.567][v][vd] Uninit decoder.
[5375.625][v][cache] Terminating cache...
[5375.625][v][cache] Cache exiting...
[5375.628][v][cplayer] finished playback, success (reason 3)
[5375.628][i][cplayer] 
[5375.628][i][cplayer] 
[5375.628][i][cplayer] Exiting... (Quit)
[5375.628][v][refreshrate] Exiting...
[5375.628][v][ytdl_hook] Exiting...
[5375.628][v][stats] Exiting...
[5375.629][v][osc] Exiting...
[5375.635][d][ao/wasapi] Uninit wasapi
[5375.635][d][ao/wasapi] Thread Reset
[5375.635][d][ao/wasapi] Thread Reset
[5375.635][d][ao/wasapi] Thread shutdown
[5375.637][d][ao/wasapi] Thread uninit done
[5375.637][d][ao/wasapi] Thread return
[5375.638][d][ao/wasapi] Uninit wasapi done
[5375.641][d][vo/gpu] flushing shader cache
[5375.645][v][vo/gpu/win32] uninit

Also important to note, that the 'out of range' entries are present in all logs when playing these files. I don't see them as the cause, unless Theater is reacting to them.

[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[5361.211][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding2]
[5361.493][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding1]
[5361.494][d][cplayer] Run command: enable-section, flags=0, args=[input, ]
[5361.494][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]
[5361.518][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]
[5361.573][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]
[5361.578][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding1]
[5361.578][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]

In the the failed log, it just ends with no errors. It just stops.

[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range

Something in Theater is getting involved.

Link to comment
Share on other sites

Guest asrequested

Maybe it has to with this stuff being introduced?

[5361.211][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding2]
[5361.493][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding1]
[5361.494][d][cplayer] Run command: enable-section, flags=0, args=[input, ]
[5361.494][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]
[5361.518][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]
[5361.573][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]
[5361.578][d][cplayer] Run command: script-binding, flags=9, args=[osc/__keybinding1]
[5361.578][d][cplayer] Run command: expand-text, flags=0, args=[${media-title}]

Maybe when mpv initiates these, Theater is impeding them, in some way? They aren't present in the failed log. So maybe that's the point at which playback, stops?

Edited by Doofus
Link to comment
Share on other sites

Guest asrequested

Another possibility is this. It too, isn't present in the failed log. So maybe the caching options in the handler/Theater are reacting to it? 

[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[1620.348][v][cache] Cache is not responding - slow/stuck network connection?
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range
[     nan][e][ffmpeg/video] h264: sps_id 1 out of range

mpv just continues to play, but not in Theater.

 

Luke, it's my opinion that you should just let mpv do what it does, and don't add any of the other options. Just feed the video to mpv.

 

EDIT:

Actually where that occurs, is not far from where the failed log, ends. Pretty close, actually. It occurs at line 2846, and the other log ends at 2594. 

Edited by Doofus
Link to comment
Share on other sites

Guest asrequested

don't add what options?

 

Anything that isn't user defined.

 

Examples

if (options.genPts) {

        list.push('--demuxer-lavf-genpts-mode=lavf');
    }

    if (options.largeCache) {

        list.push('--demuxer-readahead-secs=1800');
        list.push('--cache-secs=1800');
//list.push('--demuxer-lavf-hacks=no');
    }

    if (mediaSource.RunTimeTicks == null) {
        list.push('--demuxer-lavf-analyzeduration=3');

Anything that isn't essential or isn't a setting in UI, just don't use it. Playing videos directly in mpv, 'just works'. We should just use the basics, and maybe adjust for issues, from there. I've tried removing a few, but I get playback errors. I can only poke around, so much :)

Link to comment
Share on other sites

Guest asrequested

Those are just for live tv.

 

I was just giving examples.Those have a function. I don't know the extent of the configurations that involve mpv. If I knew what was causing this, I'd mention it. But from those logs, I would say it has something to do with that cache. It looks like when it hits that point, Theater has a hiccup, and stalls the video stream.

 

Or maybe it just needs a cache? hmmm....

Link to comment
Share on other sites

shpitz461

I think what Doofus is asking if we can relax all the arguments sent by ET for internal playback, can we start with just a simple command which is the mpv path and emby pipe?

 

Is there a way we can control these arguments with a config file anywhere in ET?

 

These are the command line arguments ET sends to MPV.exe when resuming playback:

C:\Users\nuc\AppData\Roaming\Emby-Theater\system\x64\mpv\mpv.exe --input-ipc-server=\\.\pipe\emby-pipe --idle --quiet --hwdec=no --video-output-levels=full --audio-channels=7.1,stereo --audio-spdif=ac3,eac3,dts,dts-hd,truehd --ad-lavc-ac3drc=0 --wid=132534 --no-osc

These are the arguments when ET plays the movie from beginning:

C:\Users\nuc\AppData\Roaming\Emby-Theater\system\x64\mpv\mpv.exe --input-ipc-server=\\.\pipe\emby-pipe --idle --quiet --hwdec=no --video-output-levels=full --audio-channels=7.1,stereo --audio-spdif=ac3,eac3,dts,dts-hd,truehd --ad-lavc-ac3drc=0 --wid=132534 --no-osc
Edited by shpitz461
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...