pyinstaller / pyinstaller

Freeze (package) Python programs into stand-alone executables
http://www.pyinstaller.org
Other
11.87k stars 1.94k forks source link

Python-VLC exe video not playing #4369

Closed atvKumar closed 5 years ago

atvKumar commented 5 years ago

After i compile my app the video is not playing (remains in black screen). But when i run with python the source code its working. This seems to only happen on

Windows 10 Python 3.7 pyinstaller - latest develop pyside2 - installed from wheels from qt-website (5.13)

Please do help. I am attached the sample files. I dont think its a python-vlc issue as on windows 7 32bit, compiling and video is playing. Only when i am trying it out on windows 10 i have this issue. The program loads and all other variables are all correct. Only happens after compiling.

examples.zip

htgoebel commented 5 years ago

Please provide more details, see How to report Bugs. Esp. please provide a minimal example to reproduce the error.

atvKumar commented 5 years ago

See the attached files in the first post.

htgoebel commented 5 years ago

Do you really expect me to poke for the information in some zip file? If you are to lazy to present the relevant information, why should I spend me time on it?

atvKumar commented 5 years ago

Sorry @htgoebel for the zip. Here is the sample file from python-vlc adapted to pyside2

import platform
import os
import sys

from PySide2 import QtWidgets, QtGui, QtCore
import vlc

class Player(QtWidgets.QMainWindow):

    def __init__(self, master=None):
        QtWidgets.QMainWindow.__init__(self, master)
        self.setWindowTitle("Media Player")

        # Create a basic vlc instance
        self.instance = vlc.Instance()

        self.media = None

        # Create an empty vlc media player
        self.mediaplayer = self.instance.media_player_new()

        self.create_ui()
        self.is_paused = False

    def create_ui(self):
        self.widget = QtWidgets.QWidget(self)
        self.setCentralWidget(self.widget)

        # In this widget, the video will be drawn
        if platform.system() == "Darwin": # for MacOS
            self.videoframe = QtWidgets.QMacCocoaViewContainer(0)
        else:
            self.videoframe = QtWidgets.QFrame()

        self.palette = self.videoframe.palette()
        self.palette.setColor(QtGui.QPalette.Window, QtGui.QColor(0, 0, 0))
        self.videoframe.setPalette(self.palette)
        self.videoframe.setAutoFillBackground(True)

        self.positionslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.positionslider.setToolTip("Position")
        self.positionslider.setMaximum(1000)
        self.positionslider.sliderMoved.connect(self.set_position)
        self.positionslider.sliderPressed.connect(self.set_position)

        self.hbuttonbox = QtWidgets.QHBoxLayout()
        self.playbutton = QtWidgets.QPushButton("Play")
        self.hbuttonbox.addWidget(self.playbutton)
        self.playbutton.clicked.connect(self.play_pause)

        self.stopbutton = QtWidgets.QPushButton("Stop")
        self.hbuttonbox.addWidget(self.stopbutton)
        self.stopbutton.clicked.connect(self.stop)

        self.hbuttonbox.addStretch(1)
        self.volumeslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.volumeslider.setMaximum(100)
        self.volumeslider.setValue(self.mediaplayer.audio_get_volume())
        self.volumeslider.setToolTip("Volume")
        self.hbuttonbox.addWidget(self.volumeslider)
        self.volumeslider.valueChanged.connect(self.set_volume)

        self.vboxlayout = QtWidgets.QVBoxLayout()
        self.vboxlayout.addWidget(self.videoframe)
        self.vboxlayout.addWidget(self.positionslider)
        self.vboxlayout.addLayout(self.hbuttonbox)

        self.widget.setLayout(self.vboxlayout)

        menu_bar = self.menuBar()

        # File menu
        file_menu = menu_bar.addMenu("File")

        # Add actions to file menu
        open_action = QtWidgets.QAction("Load Video", self)
        close_action = QtWidgets.QAction("Close App", self)
        file_menu.addAction(open_action)
        file_menu.addAction(close_action)

        open_action.triggered.connect(self.open_file)
        close_action.triggered.connect(sys.exit)

        self.timer = QtCore.QTimer(self)
        self.timer.setInterval(100)
        self.timer.timeout.connect(self.update_ui)

    def play_pause(self):
        if self.mediaplayer.is_playing():
            self.mediaplayer.pause()
            self.playbutton.setText("Play")
            self.is_paused = True
            self.timer.stop()
        else:
            if self.mediaplayer.play() == -1:
                self.open_file()
                return

            self.mediaplayer.play()
            self.playbutton.setText("Pause")
            self.timer.start()
            self.is_paused = False

    def stop(self):
        self.mediaplayer.stop()
        self.playbutton.setText("Play")

    def open_file(self):
        dialog_txt = "Choose Media File"
        filename = QtWidgets.QFileDialog.getOpenFileName(self, dialog_txt, os.path.expanduser('~'))
        if not filename:
            return

        # getOpenFileName returns a tuple, so use only the actual file name
        self.media = self.instance.media_new(filename[0])

        # Put the media in the media player
        self.mediaplayer.set_media(self.media)

        # Parse the metadata of the file
        self.media.parse()

        # Set the title of the track as window title
        self.setWindowTitle(self.media.get_meta(0))

        # The media player has to be 'connected' to the QFrame (otherwise the
        # video would be displayed in it's own window). This is platform
        # specific, so we must give the ID of the QFrame (or similar object) to
        # vlc. Different platforms have different functions for this
        if platform.system() == "Linux": # for Linux using the X Server
            self.mediaplayer.set_xwindow(int(self.videoframe.winId()))
        elif platform.system() == "Windows": # for Windows
            self.mediaplayer.set_hwnd(int(self.videoframe.winId()))
        elif platform.system() == "Darwin": # for MacOS
            self.mediaplayer.set_nsobject(int(self.videoframe.winId()))

        self.play_pause()

    def set_volume(self, volume):
        self.mediaplayer.audio_set_volume(volume)

    def set_position(self):

        # The vlc MediaPlayer needs a float value between 0 and 1, Qt uses
        # integer variables, so you need a factor; the higher the factor, the
        # more precise are the results (1000 should suffice).

        # Set the media position to where the slider was dragged
        self.timer.stop()
        pos = self.positionslider.value()
        self.mediaplayer.set_position(pos / 1000.0)
        self.timer.start()

    def update_ui(self):
        # Set the slider's position to its corresponding media position
        # Note that the setValue function only takes values of type int,
        # so we must first convert the corresponding media position.
        media_pos = int(self.mediaplayer.get_position() * 1000)
        self.positionslider.setValue(media_pos)

        # No need to call this function if nothing is played
        if not self.mediaplayer.is_playing():
            self.timer.stop()

            # After the video finished, the play button stills shows "Pause",
            # which is not the desired behavior of a media player.
            # This fixes that "bug".
            if not self.is_paused:
                self.stop()

def main():
    app = QtWidgets.QApplication(sys.argv)
    player = Player()
    player.show()
    player.resize(640, 480)
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

And here is the spec file for compilation used.

# -*- mode: python ; coding: utf-8 -*-
import sys
block_cipher = None

a = Analysis(['pyside2.py'],
             pathex=['E:\\Development\\python-vlc\\examples'],
             binaries=[('C:\\Program Files (x86)\\VideoLAN\\VLC\\libvlc.dll', '.'),
                        ('C:\\Program Files (x86)\\VideoLAN\\VLC\\libvlccore.dll', '.'),
                        ('C:\\Users\\Angel TV\\AppData\\Local\\Programs\\Python\\Python37-32\\Lib\\site-packages\\shiboken2\\shiboken2.abi3.dll', '.'),
                        ('C:\\Users\\Angel TV\\AppData\\Local\\Programs\\Python\\Python37-32\\Lib\\site-packages\\shiboken2\\msvcp140.dll', '.'),
                        ('C:\\Users\\Angel TV\\AppData\\Local\\Programs\\Python\\Python37-32\\Lib\\site-packages\\shiboken2\\vcruntime140.dll', '.')]
                        if sys.platform == 'win32' else [],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='vlcPython_PySideExample',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=False,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               (Tree('C:\\Program Files\\VideoLAN\\VLC\\plugins', prefix='plugins\\') if sys.platform == 'win32' else []),
               strip=False,
               upx=False,
               upx_exclude=[],
               name='pyside2')
htgoebel commented 5 years ago

This is not a minimal example, there is no error message, traceback, not build instructions. Please provide more details, see How to report Bugs. Esp. please provide a minimal example to reproduce the error. Please do not expect us to track this bug down. We can guide you, but we will are not going to track this issue down for you and not do your work. We are all volunteers here.

atvKumar commented 5 years ago

Here is the simple example with all the details you would need. The main code vlc_window.py

import os, sys
from PySide2 import QtWidgets, QtGui, QtCore
import vlc

class Player(QtWidgets.QMainWindow):
    def __init__(self, master=None):
        super(Player, self).__init__()
        self.instance = vlc.Instance('-q')
        self.mediaplayer = self.instance.media_player_new()
        self.videoframe = QtWidgets.QLabel()
        self.setCentralWidget(self.videoframe)
        self.open_video_file()

    def open_video_file(self):
        filename = QtWidgets.QFileDialog.getOpenFileName(self, "Choose Video File", os.path.expanduser('~'))
        print("file:///"+filename[0])
        self.mediaplayer.set_hwnd(int(self.videoframe.winId()))
        video_file = self.instance.media_new("file:///"+filename[0])
        self.mediaplayer.set_media(video_file)
        video_file.parse()
        self.mediaplayer.play()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    player = Player()
    player.show()
    player.resize(640, 480)
    sys.exit(app.exec_())

The spec file for pyinstaller (sorry its large, but its necessary for vlc to play when compiled)

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(['vlc_window.py'],
             pathex=['E:\\Development\\vlc_issue_test'],
             binaries=[('C:\\Program Files (x86)\\VideoLAN\\VLC\\libvlc.dll', '.'),
                        ('C:\\Program Files (x86)\\VideoLAN\\VLC\\libvlccore.dll', '.')],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='vlc_window',
          debug=True,
          bootloader_ignore_signals=False,
          strip=False,
          upx=False,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               (Tree('C:\\Program Files\\VideoLAN\\VLC\\plugins', prefix='plugins\\')),
               strip=False,
               upx=False,
               upx_exclude=[],
               name='vlc_window')

The debug output from the exe from pyinstaller. (Ok the window is showing, only the video is not being played) - This is the issue. It plays fine when i run from command line directly from python. Issue is there only when compiled.

[10356] PyInstaller Bootloader 3.x
[10356] LOADER: executable is E:\Development\vlc_issue_test\dist\vlc_window\vlc_window.exe
[10356] LOADER: homepath is E:\Development\vlc_issue_test\dist\vlc_window
[10356] LOADER: _MEIPASS2 is NULL
[10356] LOADER: archivename is E:\Development\vlc_issue_test\dist\vlc_window\vlc_window.exe
[10356] LOADER: No need to extract files to run; setting extractionpath to homepath
[10356] LOADER: SetDllDirectory(E:\Development\vlc_issue_test\dist\vlc_window)
[10356] LOADER: Already in the child - running user's code.
[10356] LOADER: Python library: E:\Development\vlc_issue_test\dist\vlc_window\python37.dll
[10356] LOADER: Loaded functions from Python library.
[10356] LOADER: Manipulating environment (sys.path, sys.prefix)
[10356] LOADER: sys.prefix is E:\Development\vlc_issue_test\dist\vlc_window
[10356] LOADER: Pre-init sys.path is E:\Development\vlc_issue_test\dist\vlc_window\base_library.zip;E:\Development\vlc_issue_test\dist\vlc_window
[10356] LOADER: Setting runtime options
[10356] LOADER: Initializing python
[10356] LOADER: Overriding Python's sys.path
[10356] LOADER: Post-init sys.path is E:\Development\vlc_issue_test\dist\vlc_window\base_library.zip;E:\Development\vlc_issue_test\dist\vlc_window
[10356] LOADER: Setting sys.argv
[10356] LOADER: setting sys._MEIPASS
[10356] LOADER: importing modules from CArchive
[10356] LOADER: extracted struct
[10356] LOADER: callfunction returned...
[10356] LOADER: extracted pyimod01_os_path
[10356] LOADER: callfunction returned...
[10356] LOADER: extracted pyimod02_archive
[10356] LOADER: callfunction returned...
[10356] LOADER: extracted pyimod03_importers
[10356] LOADER: callfunction returned...
[10356] LOADER: Installing PYZ archive with Python modules.
[10356] LOADER: PYZ archive: PYZ-00.pyz
[10356] LOADER: Running pyiboot01_bootstrap.py
[10356] LOADER: Running pyi_rth_pyside2.py
[10356] LOADER: Running vlc_window.py
file:///E:/Development/SampleVideo_1280x720_30mb.mp4

Here is the pyinstaller info when compiling

102 INFO: PyInstaller: 4.0.dev0+g515bf55a
103 INFO: Python: 3.7.4
103 INFO: Platform: Windows-10-10.0.14393-SP0
156 INFO: UPX is available.
156 INFO: Removing temporary files and cleaning cache in C:\Users\Angel TV\AppData\Roaming\pyinstaller
158 INFO: Extending PYTHONPATH with paths
['E:\\Development\\vlc_issue_test', 'E:\\Development\\vlc_issue_test']
158 INFO: checking Analysis
159 INFO: Building Analysis because Analysis-00.toc is non existent
159 INFO: Initializing module dependency graph...
162 INFO: Initializing module graph hooks...
165 INFO: Analyzing base_library.zip ...
5037 INFO: running Analysis Analysis-00.toc
5040 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable
  required by C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-32\python.exe
5164 INFO: Caching module hooks...
5175 INFO: Analyzing vlc_window.py
5569 INFO: Loading module hooks...
5569 INFO: Loading module hook "hook-encodings.py"...
5696 INFO: Loading module hook "hook-pydoc.py"...
5697 INFO: Loading module hook "hook-PySide2.py"...
6301 INFO: Loading module hook "hook-PySide2.QtCore.py"...
6654 INFO: Loading module hook "hook-PySide2.QtGui.py"...
7001 INFO: Loading module hook "hook-PySide2.QtNetwork.py"...
7723 INFO: Loading module hook "hook-PySide2.QtWidgets.py"...
8338 INFO: Loading module hook "hook-xml.py"...
8727 INFO: Looking for ctypes DLLs
8846 INFO: Analyzing run-time hooks ...
8850 INFO: Including run-time hook 'pyi_rth_pyside2.py'
8857 INFO: Looking for dynamic libraries
9675 WARNING: lib not found: shiboken2.abi3.dll dependency of C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-3
2\lib\site-packages\PySide2\QtCore.pyd
9705 WARNING: lib not found: shiboken2.abi3.dll dependency of C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-3
2\lib\site-packages\PySide2\QtGui.pyd
9749 WARNING: lib not found: shiboken2.abi3.dll dependency of C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-3
2\lib\site-packages\PySide2\QtWidgets.pyd
9777 WARNING: lib not found: shiboken2.abi3.dll dependency of C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-3
2\lib\site-packages\PySide2\QtNetwork.pyd
10553 WARNING: lib not found: shiboken2.abi3.dll dependency of C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-
32\lib\site-packages\PySide2\pyside2.abi3.dll
10623 INFO: Looking for eggs
10623 INFO: Using Python library C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-32\python37.dll
10623 INFO: Found binding redirects:
[]
10629 INFO: Warnings written to E:\Development\vlc_issue_test\build\vlc_window\warn-vlc_window.txt
10702 INFO: Graph cross-reference written to E:\Development\vlc_issue_test\build\vlc_window\xref-vlc_window.html
10741 INFO: Appending 'binaries' from .spec
10744 INFO: checking PYZ
10744 INFO: Building PYZ because PYZ-00.toc is non existent
10744 INFO: Building PYZ (ZlibArchive) E:\Development\vlc_issue_test\build\vlc_window\PYZ-00.pyz
11811 INFO: Building PYZ (ZlibArchive) E:\Development\vlc_issue_test\build\vlc_window\PYZ-00.pyz completed successfully.
11835 INFO: checking PKG
11836 INFO: Building PKG because PKG-00.toc is non existent
11838 INFO: Building PKG (CArchive) PKG-00.pkg
11866 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully.
11869 INFO: Bootloader C:\Users\Angel TV\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pyinstaller-4.0.dev
0+g515bf55a-py3.7.egg\PyInstaller\bootloader\Windows-32bit\run_d.exe
11869 INFO: checking EXE
11870 INFO: Building EXE because EXE-00.toc is non existent
11870 INFO: Building EXE from EXE-00.toc
11871 INFO: Appending archive to EXE E:\Development\vlc_issue_test\build\vlc_window\vlc_window.exe
12001 INFO: Building EXE from EXE-00.toc completed successfully.
12011 INFO: checking Tree
12012 INFO: Building Tree because Tree-00.toc is non existent
12012 INFO: Building Tree Tree-00.toc
12069 INFO: checking COLLECT
12069 INFO: Building COLLECT because COLLECT-00.toc is non existent
12071 INFO: Building COLLECT COLLECT-00.toc
27395 INFO: Building COLLECT COLLECT-00.toc completed successfully.

@htgoebel , hope that is enough. Please do tell me if i need to do more.

atvKumar commented 5 years ago

To build, you will need to have PySide2 and python-vlc installed. Also make sure you have the latest vlc player (32bit) installed on your system I am using windows 10 (64bit), python 3.7.4 (32bit), vlc(32bit) pip install vlc pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.12/latest pyside2 --trusted-host download.qt.io The pyinstaller is the latest dev version.

atvKumar commented 5 years ago

Its been so long, and still no reply. Think no one is free i think, so i am closing this. Thanks anyway. Kumar

MateKristof commented 4 years ago

I have a three +1 step solution for this problem:

Working with pyinstaller onefile "exe" like a charm

  1. Copy the "VLC" folder from the C:\Program Files\VideoLAN

  2. Paste only the VLC\plugin folder and the 2 dll files to the project root folder:

    • PycharmProjects\root\VLC\libvlc.dll
    • PycharmProjects\root\VLC\libvlccore.dll
    • PycharmProjects\root\VLC\plugins
  3. Install and use Python 3.8 interpreter and use this code section to import vlc:

try:
    # PyInstaller creates a temp folder and stores path in _MEIPASS
    base_path = sys._MEIPASS
except AttributeError:
    base_path = os.path.abspath(".")

# Python 3.8 things:
with os.add_dll_directory(os.path.join(base_path, "VLC")):
    import vlc

+1. Don't forget to add "VLC" folder to .spec file, like this:

datas=[('C:/Users/******/PycharmProjects/root/VLC', 'VLC/')],
atvKumar commented 4 years ago

If you noticed that i already did the copy pasting in the spec file, which will copy it for me. Makes it a easy build process. Not sure why 3.8 is necessary and the add_dll_directory. Is it cross platform? Not sure i want to try out your solution until you explain a little more.

Anyway thanks, Regards,

MateKristof commented 4 years ago

Your solution just not working for me, thx.

atvKumar commented 4 years ago

Your solution just not working for me, thx.

Its ok, I have already closed the issue and the project i was working on also. Made it open, and made a decision to move away from python for such projects. Moving to C++ and other frameworks, will also convince management and others to support those than python, sorry but thats how it is.

https://github.com/atvKumar/AngelSubTitlePro

mcavalcante commented 2 years ago

Your solution just not working for me, thx.

Have you found a way to solve it, Kumar? I´m experiencing the same issue.

atvKumar commented 2 years ago

Well no I have moved to other frameworks for GUI, python with vlc is just too difficult to debug and fight with.

On Tue, Nov 30, 2021 at 11:27 PM mcavalcante @.***> wrote:

Your solution just not working for me, thx.

Have you found a way to solve it, Kumar? I´m experiencing the same issue.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/pyinstaller/pyinstaller/issues/4369#issuecomment-982879913, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANCAWJUV5GMKR2Q5P62GCTUOUF7ZANCNFSM4IKRNEXA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.