j-holub / Node-MPV

A NodeJs Module for MPV Player
https://www.npmjs.com/package/node-mpv
MIT License
116 stars 73 forks source link

Jumping in and out of fullscreen #17

Closed kirkegaard closed 7 years ago

kirkegaard commented 7 years ago

I have a strange issue where mpv seems to be jumping in and out of fullscreen. Every other video will play in a window. If i hit escape while in the window it'll jump back into fullscreen though. Im unsure if this is just mpv or a wrong status being send to mpv.

This is my code. Im trying to create a watch folder that the player should loop through over and over. This is running on a Mac 10.11

let mpv = require('node-mpv');
let chokidar = require('chokidar');

let watchfolder = 'watchfolder/*';
let watcher = chokidar.watch(watchfolder, {
  ignored: /(^|[\/\\])\../
});
let player = new mpv();

let current = 0;
let playlist = []

watcher.on('add', file => {
  playlist.push(file);
});

watcher.on('unlink', file => {
  playlist = playlist.filter(item => item !== file);
});

player.on('stopped', () => {
  if (current >= playlist.length)
    current = 0;

  player.loadFile(playlist[current]);
  player.fullscreen();
  player.mute();
  console.log('Playling: ', current, playlist.length, playlist[current]);
  current++;
});
j-holub commented 7 years ago

Hey there,

at first I thought, this happens because you always call player.fullscreen(), which is supposed to do what you want, play the thing in fullscreen. But I thought maybe this toggles fullscreen as well, so I tried it out with pure MPV player and socat. But it works as intended. If MPV is already in fullscreen, it stays there.

Then I thought, maybe MPV is not ready loading the video, when player.fullscreen() is called, but it worked as well in my example.

I'm on MacOS 10.11 as well, so that should not cause the issue.

Have you tried updating to the latest MPV player? If not, which version are you using? I tested this with version 0.25.0. And could you please provide the code where you initialize node-mpv? I hardly think there's a problem with that, but just in case you know.

I get the feeling this problem is on the MPV side of things, but I might be wrong :)

kirkegaard commented 7 years ago

I think the initializing got lost in the formatting :) Just fixed it. Im also running mpv 0.25.0 from brew.

Ive actually tried uncommenting all the fullscreen calls and just have one like this

let mpv = require('node-mpv');
let chokidar = require('chokidar');

let watchfolder = '/Users/christian/Movies/watch/*';
let watcher = chokidar.watch(watchfolder, {
  ignored: /(^|[\/\\])\../
});
let player = new mpv({
  "verbose": false
});

let current = 0;
let playlist = []

watcher.on('add', file => {
  playlist.push(file);
});

watcher.on('unlink', file => {
  playlist = playlist.filter(item => item !== file);
});

player.on('stopped', () => {
  if (current >= playlist.length)
    current = 0;

  player.loadFile(playlist[current]);
  console.log('Playling: ', current, playlist.length, playlist[current]);
  current++;
});

player.loadFile(playlist[current]);
player.fullscreen();
player.mute();

But it seems to have same effect. If i watch the statuschange, it seems like its loosing the fullscreen status at some point. Sometimes its null for some reason. Ive also tried adding the fullscreen flag in my .config/mpv/mpv.conf AND setting the fullscreen flag when initializing the mpv instance but the same thing happens.

j-holub commented 7 years ago

I downloaded two videos from YouTube and did the following

let player = new mpv();

player.loadFile('file1');
player.fullscreen();

player.on('stopped', () => {
   player.loadFile('file2');
});

There was definitely some flashing when the second file was loaded, but it worked just fine. It was played in fullscreen. However the player closed the window for a short amount of time until it loaded the second file, but that was played in fullscreen.

I also tried

player.on('stopped', () => {
    player.loadFile('file2');
    player.fullscreen();
});

which worked just fine as well. Could you please try such a minimal example as well? Without the playlist array, just two files and see if that works?

kirkegaard commented 7 years ago

It looks like the stopped event is triggered before it even starts playing file1. Im never seeing file1 as it jumps straight to file2.

kirkegaard commented 7 years ago

This is what it looks like to me https://www.youtube.com/watch?v=tWS9iE03D_0

j-holub commented 7 years ago

Okay, I had put this inside of a

setTimeout(() => {
    // Code here
}, 1000);

I thought it wouldn't make a difference but indeed it does. If I remove that I have the same behavior as you do.

1

For getting to the core of the problem please try to put the stuff inside such a setTimeout method, to further investigate the fullscreen thing.

2

The problem is, that it takes a while until mpv is ready. That's why I'm working on a version 2 of this module found here.

It uses promises but it breaks the api (thus version 2) like this

let player = new mpv();
mpv.start().then(() => {
    player.loadFile('file');
    // and so on
})
.catch((error) => {
    console.log(error);
});

Since constructors cannot be asynchronous and I didn't want it returning a promise instead of the instance I changed this.

It's still under development and there's still some stuff to fix, but it will really make things better.

Super sorry for the inconvenience caused by my module =/

kirkegaard commented 7 years ago

I did some debugging and it seems like mpv exits fullscreen everytime the stopped event is called. If i load my files as a playlist it'll stay in fullscreen. But when it reaches the end the stopped event is called and the app will exit fullscreen. Again im not sure if thats your module doing that or if its just normal behaviour of mpv.

kirkegaard commented 7 years ago

Okay so, it looks like its normal behaviour for mpv to exit fullscreen after its done with the playlist. The problem seems to be that it doesnt change the fullscreen status when it exits fullscreen and fire the idle event. Therefor it still thinks its in fullscreen when i try to play the next file.

I did a small workaround that basically just sets the fullscreen to 0 then wait 1 second and reloads the playlist items and enter fullscreen again.

player.on('stopped', () => {
  player.leaveFullscreen();
  player.clearPlaylist();
  setTimeout(() => loadPlaylist(), 1000);
});

let loadPlaylist = () => {
  playlist.map(file => {
    player.append(file, 'append-play');
  });
  player.fullscreen();
}
j-holub commented 7 years ago

I see. Still strange because in my case it worked. In the minimal example given above (plus the setTimeout around) it stayed in fullscreen.

If you do

let player = new mpv();

setTimeout(() => {
   player.loadFile('file1');
   player.fullscreen();

   player.on('stopped', () => {
      player.loadFile('file2');
   });
}, 1000);

Does it really not enter fullscreen? Because in my case it really does.

Although this is natural behavior of mpv I wonder if I could do something about it. Like force it to keep fullscreen and stuff like that. Problem is though, that as said in my case in works and in yours it does not. Any suggestions?

j-holub commented 7 years ago

Any news on this?

j-holub commented 7 years ago

Closing this for now since I could not reproduce it. If you have any further information feel free to reopen the issue