Giter Site home page Giter Site logo

kagami / mpv.js Goto Github PK

View Code? Open in Web Editor NEW
396.0 17.0 66.0 4.23 MB

:movie_camera: mpv pepper plugin

License: Creative Commons Zero v1.0 Universal

Python 5.15% C++ 48.55% JavaScript 38.90% HTML 3.62% Shell 3.78%
mpv pepper ppapi electron node-webkit video player

mpv.js's Introduction

mpv
mpv.js

All format embeddable player for Electron/NW.js applications.
Powered by marvelous mpv.

Travis NPM

Get libmpv

In order to try mpv.js you need to install mpv library first.

  • Windows: download mpv-dev, unpack, put corresponding mpv-1.dll to C:\Windows\system32
  • macOS: brew install mpv
  • Linux: apt-get install libmpv1 libavformat-dev

Example

Simple Electron application yet capable of handling pretty much any available video thanks to mpv. Run:

git clone https://github.com/Kagami/mpv.js.git && cd mpv.js
npm install
# Only on Linux: npm run use-system-ffmpeg
npm run example

Usage

Add npm package

npm install mpv.js --save

Package includes prebuilt binaries for all major platforms so no need to setup compilers.

Load plugin in main process (Electron example)

const path = require("path");
const {app} = require("electron");
const {getPluginEntry} = require("mpv.js");

// Absolute path to the plugin directory.
const pluginDir = path.join(path.dirname(require.resolve("mpv.js")), "build", "Release");
// See pitfalls section for details.
if (process.platform !== "linux") {process.chdir(pluginDir);}
// Fix for latest Electron.
app.commandLine.appendSwitch("no-sandbox");
// To support a broader number of systems.
app.commandLine.appendSwitch("ignore-gpu-blacklist");
app.commandLine.appendSwitch("register-pepper-plugins", getPluginEntry(pluginDir));

Don't forget to enable plugins feature when creating BrowserWindow:

const win = new BrowserWindow({
  // ...
  webPreferences: {plugins: true},
  // ...
});

Use MPV component (React example)

const React = require("react");
const {ReactMPV} = require("mpv.js");

class Player extends React.PureComponent {
  constructor(props) {
    super(props);
    this.mpv = null;
    this.state = {pause: true, "time-pos": 0};
  }
  handleMPVReady(mpv) {
    this.mpv = mpv;
    this.mpv.observe("pause");
    this.mpv.observe("time-pos");
    this.mpv.command("loadfile", "/path/to/video.mkv");
  }
  handlePropertyChange(name, value) {
    this.setState({[name]: value});
  }
  togglePause() {
    this.mpv.property("pause", !this.state.pause);
  }
  render() {
    return (
      <ReactMPV
        className="player"
        onReady={this.handleMPVReady.bind(this)}
        onPropertyChange={this.handlePropertyChange.bind(this)}
        onMouseDown={this.togglePause.bind(this)}
      />
    );
  }
}

Currently only React component is provided.

See also

Packaging

Basically all you need to ship is mpvjs.node and mpv library. Make sure they both and also Electron/NW.js distribution have the same bitness!

Windows

You may use lachs0r builds. Copy mpv-1.dll to the directory with mpvjs.node and you are done.

macOS

Homebrew can compile libmpv.1.dylib and all its dependencies. To find dylibs that need to be packaged and fix install names you may use collect-dylib-deps script.

Linux

Two options are normally acceptable:

  1. Ask your users to install libmpv1 with package manager or simply depend on it if you build package.
  2. Compile static libmpv.so with e.g. mpv-build.

Pitfalls

Path to plugin can't contain non-ASCII symbols

This is unfortunate Chromium's pepper_plugin_list.cc restriction. To workaround this relative path might be used.

On Windows and Mac it can be done by changing working directory to the path where mpvjs.node is stored. You can't change CWD of renderer process on Linux inside main process because of zygote architecture so another fix is just cd to the plugin directory in wrapper script.

getPluginEntry helper will give you plugin entry string with that fix applied.

libmpv is being linked with Electron's libffmpeg on Linux

On Linux plugins loaded with register-pepper-plugins inherit symbols from electron binary so it leads to unfortunate effect: libmpv will use Electron's libraries which is not supported.

To workaround it you need to either replace libffmpeg.so with empty wrapper linked to libav*:

gcc -Wl,--no-as-needed -shared -lavformat -o /path/to/libffmpeg.so

Or use libmpv with statically linked libav*.

Build on x86

To build mpvjs.node by yourself you need to setup dev environment.

Step 1: setup node-gyp

See installation section.

  • Windows: Visual Studio 2013 is required

Step 2: setup NaCl SDK

See download page.

  • Windows: unpack nacl_sdk.zip to C:\
  • macOS & Linux: add export NACL_SDK_ROOT=/path/to/pepper_49 to ~/.bash_profile

Step 2.1: compile 64-bit NaCl host binaries on Windows

  1. Open C:\nacl_sdk\pepper_49\tools\host_vc.mk and replace 32_host with 64_host
  2. Open cmd, run "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64
  3. Run cd C:\nacl_sdk\pepper_49\src and make TOOLCHAIN=win PROJECTS="ppapi_cpp ppapi_gles2"

Step 3: setup mpv development files

  • Windows: download mpv-dev, unpack to C:\mpv-dev
  • macOS: brew install mpv
  • Linux: apt-get install libmpv-dev

Step 4: build plugin

  • Run node-gyp rebuild in project directory
  • Run node-gyp rebuild --arch=ia32 to build 32-bit version of plugin on 64-bit Windows

Build on ARM

Important: Electron 1.8.x ARM releases are broken so use 2.x or 1.7.x instead.

Note: instructions below have been tested on Raspberry Pi 3, see more.

Step 0: enable hardware graphics acceleration

  • Run sudo raspi-config
  • Select Advanced Options, then select GL Driver and then GL (Full KMS) OpenGL desktop driver with full KMS. When configuration is finished you will see following message: "Full KMS GL driver is enabled"
  • Select <Ok> and then <Finish> and raspi-config tool will ask you if you would like to reboot
  • Select <Yes> to reboot the system and apply configuration changes

Step 1: setup node-gyp

See installation section.

Step 2: setup NaCl SDK

The NaCl SDK itself is only built to run on x86, so you can't use ./naclsdk. Instead you have to download pepper's archive directly and unpack it to some directory. Then add export NACL_SDK_ROOT=/path/to/pepper_49 to ~/.bash_profile.

Step 3: setup mpv development files

apt-get install libmpv-dev

Step 4: compile ARM host binaries

Run cd /path/to/pepper_49/src and make TOOLCHAIN=linux PROJECTS="ppapi_cpp ppapi_gles2" CFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0".

Step 5: build plugin

After the process is done, head back to mpv.js directory and run node-gyp rebuild.

Applications using mpv.js

Feel free to PR your own.

License

mpv.js is licensed under CC0 itself. However if you use GPL build of libmpv (e.g. lachs0r builds) your application might violate GPL dynamic linking restrictions. LGPL build should be safe, see mpv copyright for details. (This is not a legal advice.)

Example video is part of Tears of Steel movie (CC) Blender Foundation | mango.blender.org.

Logo is by @SteveJobzniak.

mpv.js's People

Contributors

dependabot[bot] avatar kagami avatar peter23 avatar qsniyg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mpv.js's Issues

Plugin could not be loaded error

Hello, I am trying to get this awesome, awesome project to work in my electron app. However, I am struggling with getting it to run. I put the code from

Load plugin in main process (Electron example)

of your readme to the electron-starter.js file that the electron quick start app generates, e.g. the file that boots up electron and creates a window. Here is a full gist of that file. However, all I see is an error saying that the plugin could not be loaded.

Can you help?

not able to apply video filter

Hi Kagami,

I'm try to using video filter with mpv.js. It works for command line version of mpv:

'''
mpv THE_BRIDGE.avi --vf=lavfi=[gradfun=20:30,vflip]
'''
The video will be flipped while playing.

I tried to do the same thing from mpv.js, by using reactmpv's property method:

'''
this.mpv.property('vf', "lavfi=[gradfun=20:30,vflip]");
'''

But the mpv.js just stopped work, and nothing else happened.

Could you please let me know the correct way to do it? Thanks.

Edward.

Prerequisites for build on Windows

Hi,

This seems like a very nice approach for supporting all these video file formats in electron apps.

Are there any prerequisites for the build to work on Windows? Any SDKs that I should install first, and build after?

I don't really have any experience with plugins and how they integrate with electron

[libmpv_render] fails to render textures

due to a perfectly legitimate desire to maintain backward compatibility with older Raspberry models, the repository only provides a generic build of mpv (and an older version of FFmpeg). As a result, mpv is unable to take advantage of hardware acceleration, and therefore does not leverage the Raspberry’s surprisingly powerful on-board GPU to play video. So I used mpv-build to build FFmpeg and MPV from their master branch. with these options.

ffmpeg:

--enable-gpl
--enable-nonfree
--enable-static
--enable-libx264
 --enable-libfdk-aac
 --enable-libvpx
 --enable-libopus
 --enable-libmp3lame
 --enable-libtheora
 --enable-libvorbis
 --enable-omx
 --enable-omx-rpi
 --enable-mmal
 --enable-libxcb
 --enable-libfreetype
 --enable-libass
 --enable-gnutls
 --disable-opencl
 --extra-cflags="-march=armv8-a+crc -mfpu=neon-fp-armv8 -mtune=cortex-a53"

mpv:

--enable-rpi
--enable-libmpv-shared

the result is astonishing, MPV (player itself) can play 1080P/60fps videos without dropping a single frame.
but libmpv will show a white screen that can only play the sounds and render subtitles. logs from MPV_TERMINAL indicate these errors:

[libmpv_render] after creating texture: OpenGL error INVALID_VALUE.
[libmpv_render] Error: framebuffer completeness check failed (error=36054).
[libmpv_render] Error: texture could not be created.

I've already rebuild the plugin, but the issue remains. also this is sort of similar to #25 but i've tried it with 1.7.9 as well.

`command` not working on example

Video is not playing after pressing play (or trying to load another video) when doing npm run example on master.

It works if I manually override and put mpv_command(mpv_, "loadfile", "path/to/video", NULL); with the exact same strings that were passed.

PS: On macOS 10.12.3.

How to listen stream stop event ?

I use mpv.js to play .flv live stream. I need to know the stream end event happen and display end message, I have tried observe 'eof-reached' and 'stream-end', but neither emitted when the stream stop.

Handle complex properties + Promise API

currently there is no method for getting a property value like mp.get_property. sure there is mpv.observe but it's not useful for some properties like track-list

the following code demonstrates why:

  handleMPVReady (mpv) {
    this.mpv = mpv
    this.mpv.observe("track-list")
    this.mpv.observe("track-list/count")
  }

  handlePropertyChange(name, value) {
    if (name === 'track-list') console.log(value) // noting, where it should be an array
    if (name === 'track-list/count') console.log(value) // integer
  }

so in order to find out the number of subtitles that are available for the current file and then cycle through them first you have to find the number of tracks then observe each track individually like
this.mpv.observe('track-list/0/type').

my workaround

since #24 is solved. I can load a custom script that uses mp.get_property('track-list') and then spawn PowerShell to write the result into a temporary file. and then with fs.watch and fs.createReadStream feed the result into renderer process.

script.js

mp.set_property('sub-auto', 'fuzzy')

var getTempDir = function () {
  var temp = mp.utils.getenv('TEMP') || mp.utils.getenv('TEP')
  if (temp) return temp
  else return '/tmp'
}

mp.register_event('file-loaded', function () {
  var trackList = mp.get_property('track-list')
  var cmds = ['powershell', "'" + trackList + "' | Out-File -Encoding 'UTF8' " + getTempDir() + '\\mpvdata.json']
  var result = mp.utils.subprocess({
    args: cmds
  })
})

renderer.js

  handleMPVReady (mpv) {
    this.mpv = mpv
    this.mpv.command('load-script', path.join(__dirname, 'mpv', 'config', 'scripts', 'index.js'))
    const observe = mpv.observe.bind(mpv);
    ['pause', 'time-pos', 'duration', 'eof-reached', 'volume', 'mute'].forEach(observe)
  }


  handleLoad (e) {
    e.target.blur()
    const items = remote.dialog.showOpenDialog({filters: [
      {name: 'Videos', extensions: ['mkv', 'mp4', 'mov', 'avi']},
      {name: 'All files', extensions: ['*']}
    ]})
    if (items) {
      this.mpv.command('loadfile', items[0])
      this.mpv.property('pause', false)
      let trackList = ''
      setTimeout(() => {
        fs.createReadStream(path.join(os.tmpdir(), 'mpvdata.json'))
          .on('data', (chunks) => {
            trackList += chunks
          })
          .on('end', () => {
            console.log(trackList)
          })
      }, 1000)
    }
  }

it is not an accurate solution because:

  • this only works on windows.
  • if powershell fails I have to ether close the MPV process. or ignore the functionality that uses track-list in my program.

Is there a way to debug compatible issue?

Hi Kagami,

I'm working on a video player for macOS, which use mpv.js as its video playback engine.

Most of the users use this player just fine, everything works perfectly.

But some of them complained that they can not play any mkv files. The video player displayed a green screen only (audio is ok).

I'm not quite clear about what happened. Is there anyway to get some useful debug info from mpv.js?

BTW, I suspected it is related to hardware decoding. But the default settings of hardware decoding is off (hwdec=no). So this is probably a dead end.

I also tried to set another value for vo, but from the doc of mpv.io, I can not find a reasonable value to replace the default "gpu" one.

So now I'm blocked by this problem, any suggestion is highly welcome, thanks!

Unable to play some h264 or hevc videos on Electron 2.x + mpv.js

Hi Kagami,

I found a strange issue that mpv.js is not able to play some h264 or hevc videos with Electron 2.x.

I try the same videos with Electron 1.8.8 and Electron 3.0.x, they don't have this issue.

If you need to reproduce this problem, I can put a link to the sample video.

Thanks.

"loadfile" command with additional arguments

I'm trying to call a "loadfile" command with additional arguments. Like :
this.mpv.command('loadfile', 'file://' + PATH_TO_FILE, 'replace', ["--start=0", "--end=10"])

In this case video is not loading at all. Can you help ?

"Couldn't load plugin" on Electron 5.0.5

While the example code with Electron 1.8.8 woks great, as soon as I upgrade the electron version I get "Couldn't load plugin".

Is there something else I need to do to get it working? I've re-run npm install and there's nothing in the terminal or browser dev tools console. It appears in navigator.plugins in the browser.

Can I embed this plugin into the webpage?

The example you gave is embedded in the desktop application. If I want to embed this plugin into the webpage, can I do it? What should I do? Is there a relevant example?

Plug-in can not be loaded

hi I encountered some problems. i use ubuntu 16.04.

mpv-build install ok;

$ ls /usr/include/mpv 
client.h  opengl_cb.h  qthelper.hpp

$ tree -I node_modules
.
├── binding.gyp
├── build
│   └── Release
│       └── mpvjs.node
├── COPYING
├── example
│   ├── index.html
│   ├── index.js
│   ├── mpv
│   │   └── mpvjs.node
│   ├── renderer.js
│   └── tos.mkv
├── index.cc
├── index.js
├── libffmpeg.so
├── package.json
├── README.md
├── scripts
│   └── collect-dylib-deps.sh
└── yarn.lock

gcc -shared -lavformat -o node_modules/electron/dist/libffmpeg.so 
/usr/bin/ld: not found -lavformat

Please help me to see

cannot work in windows 32bit

Dear Kagami, when i pack with 'electron-packager' for windows 32bit, it just cannot work. tips 'Cannot load plug-ins'. Curiously, it work in 64bit. what can I do.

Subtitles

How can I work with subtitles.
for example:

  1. load subtitles from video;
  2. add subtitles to video.

Couldn't load plugin.

When I run the example app I get the message "Couldn't load plugin." in the middle of the electron window. Perhaps I am using incompatible versions?
Thanks!

Environment:

Ubuntu 18.04.1 LTS 64bit
$ electron --version v3.0.10
$ node --version v10.11.0

$ mpv --version
mpv 0.27.2 (C) 2000-2017 mpv/MPlayer/mplayer2 projects
 built on UNKNOWN
ffmpeg library versions:
   libavutil       55.78.100
   libavcodec      57.107.100
   libavformat     57.83.100
   libswscale      4.8.100
   libavfilter     6.107.100
   libswresample   2.9.100
ffmpeg version: 3.4.4-0ubuntu0.18.04.1

$ readelf -d node_modules/electron/dist/libffmpeg.so
Dynamic section at offset 0xe40 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libavformat.so.57]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x460
 0x000000000000000d (FINI)               0x57c
 0x0000000000000019 (INIT_ARRAY)         0x200e30
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x200e38
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x1b8
 0x0000000000000005 (STRTAB)             0x2e0
 0x0000000000000006 (SYMTAB)             0x1f0
 0x000000000000000a (STRSZ)              161 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x201000
 0x0000000000000007 (RELA)               0x3b8
 0x0000000000000008 (RELASZ)             168 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x398
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x382
 0x000000006ffffff9 (RELACOUNT)          3
 0x0000000000000000 (NULL)               0x0

Couldn't load plugin.

I'm trying to run example, but react can't render Player component. It's just say "Couldn't load plugin."
Any ideas how to fix this?

Set mpv options (e.g. --loop-file=inf)?

How do you set the --loop-file option to inf?

It would seem this is not a property. Attempting to set it as a property causes the Electron app to crash. I've tried sending it as a command as well to no avail. I think you need to set this option prior to the embed but I'm not certain if there's a way to do that with mpv.js?

Thanks.

(P.S. This is an amazing library. I've currently got it running in an Ember powered Electron app.)

feat: Standalone app

It would be great if we could pack everything in one stand alone app instead to mess around with brew/apt or moving files into system32.

Subtitles

How can I work with subtitles?
It will not automatically associate

onError callback

Makes sense to be able to receive notifications for e.g. failed commands. Might also use Promise API for API methods.

Minimal os requirements for macOS

Hello, one of my user found mpv.js displaying "Couldn't load plugin" on OSX 10.11.6.

So what is the minimal os requirements of mpv.js? Thanks.

Impossible to run it on systems without OpenGL (without video drivers)

In such cases plugin can not be loaded and message
failed to initialize mpv GL context
can be seen in the console.

This problem happens for example on virtual machines without guest OS tools installed.

I know that playing video through OpenGL is a really good way.
But I think also will be good to have some fallback option to run it on systems without OpenGL.

mpv crashes when loading custom scripts

I followed the documentation on lua scripting and since options can be set as runtime via properties as well the following line should load my custom script

this.mpv.property('script', path.join(__dirname, 'mpv_commons.lua'))

but instead it just crashed

os: windows 10_x64 build 16299
electron: 1.8.4

screenshots

OpenGL error in electron 2.0.0

electron 2.0.0 was released yesterday and I tried it with mpv.js. everything looks fine but I get this Error message in my console. it doesn't seems to be affecting the player functionality but nevertheless it's an error.

os: windows 10_x64 build 16299
electron: 2.0.0

[11664:0503/170106.364:ERROR:texture_manager.cc(2437)] [.PPAPIContext]GL ERROR :GL_INVALID_VALUE : glTexImage2D: invalid internal_format GL_RGBA16_EXT
[opengl-cb] after creating texture: OpenGL error INVALID_VALUE.
[opengl-cb] Error: framebuffer completeness check failed (error=36054).
[opengl-cb] Error: texture could not be created.

Hardware Acceleration

Hi Kagami,

I was able to use your plugin to with GPU acceleration by changing vo from opengl-cb to default and hwdec to various values. Full screen videos play much faster but are not rendered within the browser window.

My goal is a full screen accelerated render of videos alternating with HTML content, so it would be nice if I could get this to work as a plugin rather than find a way to control the window that mpv creates.

Is it the case that opengl-cb video output necessary for a ppapi plugin to render in the browser window?

I know this is outside the original purpose of your plugin, but do you have any advice in this area?

Thanks.

"Couldn't load plugin" on Ubuntu 16.04

I downloaded the git example, and run it.
But can't working on the ubuntu 16.04.
I installed the mpv using apt-get.And the mpv player can working successfully.
Please help me, I tryed it's OK on windows 10, but in ubuntu 16.04 is failture.

build on ARMhf7

both mpv and pepper_49 support ARM. so I tried to build this project with libraries under /pepper_49/lib/glibc_arm although lppapi is missing so I copied the one under linux_host.

and to put everyting together. I used electron 1.8.7 on RaspberryPi 3 (armhf7)
somehow it faild to even load the page. so I used 2.0.7. now it says "couldn't load the plugin". so any advice?

Support for mpv 0.28.0

Hi, any plans to support the latest mpv version? (released Dec 25th)

Something seems to be broken at the moment.

v47 prebuilds

when trying to build my application, it looks for releases in the repo marked for v47, but it only finds for v42. any other way of solving it apart from building my own?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.