Jump to content


Photo

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

3D MVC Freeze mk3d

  • Please log in to reply
206 replies to this topic

#121 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 03:32 PM

Today I'm running tests on this. I'm stripping out a whole bunch of things from the playbackhandler, that have to do with video. So far, no change. There isn't much more I can remove. No errors are being reported. It's like the stream just ends. I'm starting to think this has to do with delivery, as opposed to playback handling.



#122 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 03:38 PM

I do see this in the server log, where it says 'unknown profile'. I don't know if that would make a difference?

2018-09-29 11:45:05.131 Info App: User policy for Peter. EnablePlaybackRemuxing: True EnableVideoPlaybackTranscoding: True EnableAudioPlaybackTranscoding: True
2018-09-29 11:45:05.131 Info App: Profile: Unknown Profile, Path: \\Htpc\d\Temp Movie Library\Wonder Woman 3D\Wonder Woman 3D.mkv, isEligibleForDirectPlay: True, isEligibleForDirectStream: True
2018-09-29 11:45:05.131 Info App: RemoteClientBitrateLimit: 20000000, RemoteIp: 10.1.1.13, IsInLocalNetwork: True
2018-09-29 11:45:05.131 Info App: Profile: Unknown Profile, Path: \\Htpc\d\Temp Movie Library\Wonder Woman 3D\Wonder Woman 3D.mkv, isEligibleForDirectPlay: True, isEligibleForDirectStream: True
2018-09-29 11:45:05.131 Info App: RemoteClientBitrateLimit: 20000000, RemoteIp: 10.1.1.13, IsInLocalNetwork: True
2018-09-29 11:45:05.131 Info App: Profile: Unknown Profile, Path: \\Htpc\d\Temp Movie Library\Wonder Woman 3D\Wonder Woman 3D.mkv, isEligibleForDirectPlay: True, isEligibleForDirectStream: True


#123 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 03:41 PM

And then, when it stops

2018-09-29 12:12:06.698 Info HttpServer: HTTP POST http://10.1.1.14:8096/emby/Sessions/Playing/Stopped. UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) EmbyTheater/3.0.2 Chrome/61.0.3163.100 Electron/2.0.6 Safari/537.36
2018-09-29 12:12:06.699 Debug App: ReportPlaybackStopped PlaySessionId: 
2018-09-29 12:12:06.699 Info SessionManager: Playback stopped reported by app Emby Theater 3.0.2 playing Wonder Woman. Stopped at 1588921 ms
2018-09-29 12:12:06.700 Info HttpServer: HTTP Response 204 to 10.1.1.13. Time: 2ms. http://10.1.1.14:8096/emby/Sessions/Playing/Stopped 


#124 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 03:43 PM

So it looks like the server thinks that the app just pressed 'stop', which it didn't.



#125 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 03:59 PM

I'm testing again, to get more accurate start/stop times



#126 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 04:23 PM

Scratch that. The server reports that it continues playing. I think that was established, earlier. 



#127 Luke OFFLINE  

Luke

    System Architect

  • Administrators
  • 157111 posts
  • Local time: 01:34 AM

Posted 29 September 2018 - 04:24 PM

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



#128 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 04:39 PM

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. 



#129 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 29 September 2018 - 05:01 PM

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;



#130 shpitz461 OFFLINE  

shpitz461

    Advanced Member

  • Members
  • 194 posts
  • Local time: 12:34 AM
  • LocationAcworth, GA

Posted 30 September 2018 - 03:40 PM

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.



#131 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 30 September 2018 - 03:58 PM

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.



#132 shpitz461 OFFLINE  

shpitz461

    Advanced Member

  • Members
  • 194 posts
  • Local time: 12:34 AM
  • LocationAcworth, GA

Posted 30 September 2018 - 04:39 PM

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.



#133 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 30 September 2018 - 04:43 PM

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.



#134 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 30 September 2018 - 04:44 PM

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, 30 September 2018 - 04:45 PM.


#135 Luke OFFLINE  

Luke

    System Architect

  • Administrators
  • 157111 posts
  • Local time: 01:34 AM

Posted 30 September 2018 - 10:50 PM

It gets the list of video streams in the current source.



#136 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 30 September 2018 - 11:25 PM

Thanks. I'm about out of ideas, on this. Something in Theater is causing it, but it's beyond my knowledge.



#137 shpitz461 OFFLINE  

shpitz461

    Advanced Member

  • Members
  • 194 posts
  • Local time: 12:34 AM
  • LocationAcworth, GA

Posted 01 October 2018 - 08:12 AM

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?



#138 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 01 October 2018 - 10:21 AM

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.

#139 shpitz461 OFFLINE  

shpitz461

    Advanced Member

  • Members
  • 194 posts
  • Local time: 12:34 AM
  • LocationAcworth, GA

Posted 01 October 2018 - 11:02 AM

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.



#140 Guest_asrequested_* OFFLINE  

Guest_asrequested_*
  • Guests

Posted 01 October 2018 - 12:58 PM

If you use the mpv standalone, you'll see the same thing, but playback won't stop.





Also tagged with one or more of these keywords: 3D, MVC, Freeze, mk3d

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users