2

I am trying to install python-shout module in windows 10 but it fails. In the ubuntu works well.

Edit (06/10/2022): Here is what i have tried to build python-shout in native windows

  1. Only download libshout module files from here: Note that i download all the 14 dependencies + this package: winpthreads
  2. I renamed the 15 zst files to have names like 1.zst, 2.zst,..., 15.zst
  3. I decompress the zst files using this command: tar --use-compress-program=unzstd -xvf 1.zst
  4. From the output files and directories i copied the opt/x86_64-w64-mingw32/* folders and files in mingw64 folder.
  5. After that i uninstall msys2 platform.
  6. I open a cmd and i run the file mingw64/bin/shout.exe The files run correctly.
  7. I download and extract the python-shout module from here
  8. I modified the setup.py of the extracted folder in step 7 to be like
# distutils build script
# To install shout-python, run 'python setup.py install'

from setuptools import setup, Extension
import os
import sys
import setuptools

ver = '0.2.7'

with open("README.md", "r") as fh:
    long_description = fh.read()

cflags = "-IC:/Users/cpapp/OneDrive/Υπολογιστής/mingw64/include"
libs = "-LC:/Users/cpapp/OneDrive/Υπολογιστής/mingw64/lib -lshout"

# there must be an easier way to set up these flags!
iflags = [x[2:] for x in cflags.split() if x[0:2] == '-I']
extra_cflags = [x for x in cflags.split() if x[0:2] != '-I']
libdirs = [x[2:] for x in libs.split() if x[0:2] == '-L']
libsonly = [x[2:] for x in libs.split() if x[0:2] == '-l']

# include_dirs=[]
# libraries=[]
# runtime_library_dirs=[]
# extra_objects, extra_compile_args, extra_link_args
shout = Extension('shout', sources = ['shout.c'],
                  include_dirs = iflags,
                  extra_compile_args = extra_cflags,
                  library_dirs = libdirs,
                  libraries = libsonly)

# data_files = []
setup (name = 'python-shout',
       version = ver,
       description = 'Bindings for libshout 2',
       long_description=long_description,
       long_description_content_type="text/markdown",
       url = 'http://icecast.org/download.php',
       author = 'Brendan Cully',
       author_email = 'brendan@xiph.org',
       ext_modules = [shout],
       packages=setuptools.find_packages(),
       classifiers=[
                   "Programming Language :: Python :: 3",
                   "Programming Language :: Python :: 2",
                   "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
                   "Operating System :: OS Independent",
               ],

       )

Important note: Check the path values of cflags and libs variables.

  1. I run python setup.py build with this output:
running build
running build_ext
building 'shout' extension
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\HostX86\x86\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IC:/Users/cpapp/OneDrive/Υπολογιστής/mingw64/include -IC:\python\include -IC:\python\Include "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\ATLMFC\include" "-IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt" /Tcshout.c /Fobuild\temp.win32-cpython-310\Release\shout.obj
shout.c
"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\HostX86\x86\link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:/Users/cpapp/OneDrive/Υπολογιστής/mingw64/lib /LIBPATH:C:\python\libs /LIBPATH:C:\python /LIBPATH:C:\python\PCbuild\win32 "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\ATLMFC\lib\x86" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\lib\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\ATLMFC\lib\x86" "/LIBPATH:C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\lib\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\\um\x86" shout.lib /EXPORT:PyInit_shout build\temp.win32-cpython-310\Release\shout.obj /OUT:build\lib.win32-cpython-310\shout.cp310-win_amd64.pyd /IMPLIB:build\temp.win32-cpython-310\Release\shout.cp310-win_amd64.lib
LINK : fatal error LNK1181: cannot open input file 'shout.lib'
error: command 'C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.33.31629\\bin\\HostX86\\x86\\link.exe' failed with exit code 1181

The error is that shout.lib file can't be found, but there is no shout.lib file only libshout-3.dll. I tried to convert libshout-3.dll to shout.lib using dumpbin. The python module installation works well but when i am trying to import the module not well formatted dll error oquered.

Any help would be usefull!!

Chris P
  • 2,059
  • 4
  • 34
  • 68

3 Answers3

1

I have succesfully install python-shout module with MingGW and MSYS 2.

Instructions:

  1. Download msys2 from https://repo.msys2.org/distrib/x86_64/msys2-x86_64-20210228.exe

  2. Run the installer (instructions: https://www.msys2.org/)

  3. Update packages using pacman -Syu and pacman -Su

  4. Install basic programs for msys2 pacman -S --needed base-devel mingw-w64-x86_64-toolchain

  5. Install python pacman -S mingw-w64-x86_64-python

  6. Install libshout pacman -S mingw-w64-x86_64-libshout

  7. Download and extract python-shout from: https://github.com/yomguy/python-shout

  8. Edit setup.py to be like this:

from setuptools import setup, Extension
import os
import sys
import setuptools

ver = '0.2.7'

with open("README.md", "r") as fh:
    long_description = fh.read()

cflags = "-IC:/msys64/mingw64/include"
libs = "-LC:/msys64/mingw64/lib -lshout"

# there must be an easier way to set up these flags!
iflags = [x[2:] for x in cflags.split() if x[0:2] == '-I']
extra_cflags = [x for x in cflags.split() if x[0:2] != '-I']
libdirs = [x[2:] for x in libs.split() if x[0:2] == '-L']
libsonly = [x[2:] for x in libs.split() if x[0:2] == '-l']

# include_dirs=[]
# libraries=[]
# runtime_library_dirs=[]
# extra_objects, extra_compile_args, extra_link_args
shout = Extension('shout', sources = ['shout.c'],
                  include_dirs = iflags,
                  extra_compile_args = extra_cflags,
                  library_dirs = libdirs,
                  libraries = libsonly)

# data_files = []
setup (name = 'python-shout',
       version = ver,
       description = 'Bindings for libshout 2',
       long_description=long_description,
       long_description_content_type="text/markdown",
       url = 'http://icecast.org/download.php',
       author = 'Brendan Cully',
       author_email = 'brendan@xiph.org',
       ext_modules = [shout],
       packages=setuptools.find_packages(),
       classifiers=[
                   "Programming Language :: Python :: 3",
                   "Programming Language :: Python :: 2",
                   "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
                   "Operating System :: OS Independent",
               ],

       )
  1. Install setuptools pacman -S python-setuptools

  2. Install python-shout running: 10.a cd c/Users/Χρήστος/Desktop/python-shout-master Note that you must put your Windows username instead of mine (Χρήστος) and 10.b python setup.py install

and that's it. Python-shout module has successfully installed in your Windows machine. To test it just run:

python 
>>import shout
>>s = shout.Shout()
>>print("Using libshout version %s" % shout.version())

After that you can install pyinstaller from source in MSYS2 console (https://github.com/pyinstaller/pyinstaller) download and extract, then run python setup.py install

and finally run pyinstaller --onefile icecast_program.py

and then you will have an exe that can be run in every Windows system.

Chris P
  • 2,059
  • 4
  • 34
  • 68
1

Here is a simple but good solution.

  1. First install msys2, python for msys2, libshout for msys2, pip for msys2, pyinstaller for python for msys2, setuptools for python for msys2 and everything else to build python-shout module in msys2 platform.
  2. After installation of python-shout in msys2 platform i create an exe (using pyinstaller). The code of this file is:
import shout
import ast

x = ""
while(x is not "stop"):
    try:
        x = input()
        if x == "stop":
            break
        else:
            if "s.get_connected()" in x:
                connected_status = int(s.get_connected())
                print(connected_status)
            elif "list_bytes=" not in x:
                exec(x)
            else:
                x = x.replace("list_bytes=","")
                original_list = ast.literal_eval(x)
                s.send(bytes(original_list))
                s.sync()
    except Exception as e:
        print(str(e))

The above code uses libshout and python-shout that have been installed in msys2 for use in native windows.

  1. After creating the .exe (msys_shout.exe) of the up file, i wrote the following file that uses the msys_shout.exe:
import os
import sys
from subprocess import Popen, PIPE
from pydub import AudioSegment
from pydub.utils import which
AudioSegment.converter = which("ffmpeg.exe")

from threading  import Thread
from queue import Queue, Empty
ON_POSIX = 'posix' in sys.builtin_module_names

import time
import io

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

p1 = Popen(["msys_shout.exe"], stdin=PIPE, stdout=PIPE,shell=False, universal_newlines=True, bufsize=1, close_fds=ON_POSIX)
q = Queue()
t = Thread(target=enqueue_output, args=(p1.stdout, q))
t.daemon = True # thread dies with the program
t.start()
time.sleep(2)

#create icecast connection
p1.stdin.write('s = shout.Shout()\n')
p1.stdin.flush()

p1.stdin.write('s.audio_info = {shout.SHOUT_AI_BITRATE:\'128\', shout.SHOUT_AI_SAMPLERATE:\'44800\', shout.SHOUT_AI_CHANNELS:\'2\'}\n')
p1.stdin.flush()

p1.stdin.write('s.name = \'Test radio connection\'\n')
p1.stdin.flush()

p1.stdin.write('s.url = \'http://localhost/test.ogg\'\n')
p1.stdin.flush()

p1.stdin.write('s.mount = \'test.ogg\'\n')
p1.stdin.flush()

p1.stdin.write('s.port = 8000\n')
p1.stdin.flush()

p1.stdin.write('s.user = \'username\'\n')
p1.stdin.flush()

p1.stdin.write('s.password = \'password\'\n')
p1.stdin.flush()

p1.stdin.write('s.genre = \'Other\'\n')
p1.stdin.flush()

p1.stdin.write('s.description = \'Test description\'\n')
p1.stdin.flush()

p1.stdin.write('s.host = \'localhost\'\n')
p1.stdin.flush()

p1.stdin.write('s.format = \'ogg\'\n')
p1.stdin.flush()

p1.stdin.write('s.open()\n')
p1.stdin.flush()

time.sleep(2)

p1.stdin.write('s.get_connected()\n')
p1.stdin.flush()

#connected_status = int(p1.stdout.readline())
time.sleep(2)
try:
    connected_status = int(q.get_nowait())
except Empty:
    connected_status = -2
    
if(connected_status==0):
    connected = True
    connected_message = "No error"
elif(connected_status==-1):
    connected = False
    connected_message = "Nonsensical arguments e.g. self being NULL"
elif(connected_status==-2):
    connected = False
    connected_message = "Couldn't connect"
elif(connected_status==-3):
    connected = False
    connected_message = "Login failed"
elif(connected_status==-4):
    connected = False
    connected_message = "Socket error"
elif(connected_status==-5):
    connected = False
    connected_message = "Out of memory"
elif(connected_status==-6):
    connected = False
    connected_message = "-"
elif(connected_status==-7):
    connected = True
    connected_message = "Connected in progress...Send data"
elif(connected_status==-8):
    connected = False
    connected_message = "Not connected"
elif(connected_status==-9):
    connected = False
    connected_message = "This libshout doesn't support the requested option"
elif(connected_status==-10):
    connected = False
    connected_message = "Socket is busy"
elif(connected_status==-11):
    connected = False
    connected_message = "TLS requested but not supported by peer"
elif(connected_status==-12):
    connected = False
    connected_message = "TLS connection can not be established because of bad certificate"
elif(connected_status==-13):
    connected = False
    connected_message = "Retry last operation"

print(connected_message)

audio_segment = AudioSegment.from_file("1.mp3", format="mp3").set_frame_rate(44800)
total_duration_milliseconds = len(audio_segment)
chunk_number = 0
packet_time = 744

while(True):
    try:
        try:
            error_msg = q.get_nowait()
            print(error_msg)
            p1.stdin.write('stop\n')
            p1.stdin.flush()
            break
        except Empty:
            pass

        t1 = time.time()
        if((chunk_number+1)*(packet_time)<=total_duration_milliseconds):
            slice = audio_segment[chunk_number*(packet_time):(chunk_number+1)*(packet_time)]
            chunk_number+=1
            send_data = io.BytesIO()
            slice.export(send_data,format="ogg",bitrate="128k")
            send_data_final = send_data.getvalue()
            send_data_list = list(send_data_final)
            
            p1.stdin.write('list_bytes='+str(send_data_list)+'\n')
            p1.stdin.flush()
            
        else:
            if((chunk_number)*(packet_time)<total_duration_milliseconds):
                slice = audio_segment[chunk_number*(packet_time):]
                send_data = io.BytesIO()
                slice.export(send_data,format="ogg",bitrate="128k")
                send_data_final = send_data.getvalue()
                send_data_list = list(send_data_final)
                
                p1.stdin.write('list_bytes='+str(send_data_list)+'\n')
                p1.stdin.flush()
                
                chunk_number = 0
                continue
            else:
                chunk_number = 0
                continue
        t2 = time.time()
        diff = (t2 - t1)
        if diff<packet_time/1000-0.1:
            time.sleep(packet_time/1000-diff-0.1)
    except Exception as e:
        print(e)
#s.close() command

This file was run under windows cmd. It uses pydub (AudioSegment), subprocess.Popen, ffmpeg and of course the compiled msys_shout.exe script!

Why I don't use msys2 python-shout module directly: The reason is that in my project I want to use PyQtWebEngine python module that msys2 can't provide me (only QtWebView, but I want more functionalities).

halfer
  • 19,824
  • 17
  • 99
  • 186
Chris P
  • 2,059
  • 4
  • 34
  • 68
0

Looking at the setup.py, it looks like the package just doesn't support Windows. All those os.system() calls are POSIX-only.

  • The subject is what can i use instead? – Chris P Apr 16 '21 at 17:42
  • While I agree that the calls seem POSIX only (prominently the various pipes to `/dev/null`) the same file uses the classifier `"Operating System :: OS Independent"`, suggesting that it does support not just POSIX. – MisterMiyagi Oct 06 '22 at 11:57