Install python shout module in windows 10 (python version 3.9)

Question:

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 = '[email protected]',
       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 FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629binHostX86x86cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IC:/Users/cpapp/OneDrive/Υπολογιστής/mingw64/include -IC:pythoninclude -IC:pythonInclude "-IC:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629include" "-IC:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629ATLMFCinclude" "-IC:Program FilesMicrosoft Visual Studio2022CommunityVCAuxiliaryVSinclude" "-IC:Program Files (x86)Windows Kits10include10.0.19041.0ucrt" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\um" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\shared" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\winrt" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\cppwinrt" "-IC:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629include" "-IC:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629ATLMFCinclude" "-IC:Program FilesMicrosoft Visual Studio2022CommunityVCAuxiliaryVSinclude" "-IC:Program Files (x86)Windows Kits10include10.0.19041.0ucrt" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\um" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\shared" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\winrt" "-IC:Program Files (x86)Windows Kits10\include10.0.19041.0\cppwinrt" /Tcshout.c /Fobuildtemp.win32-cpython-310Releaseshout.obj
shout.c
"C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629binHostX86x86link.exe" /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:/Users/cpapp/OneDrive/Υπολογιστής/mingw64/lib /LIBPATH:C:pythonlibs /LIBPATH:C:python /LIBPATH:C:pythonPCbuildwin32 "/LIBPATH:C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629ATLMFClibx86" "/LIBPATH:C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629libx86" "/LIBPATH:C:Program Files (x86)Windows Kits10lib10.0.19041.0ucrtx86" "/LIBPATH:C:Program Files (x86)Windows Kits10\lib10.0.19041.0\umx86" "/LIBPATH:C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629ATLMFClibx86" "/LIBPATH:C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629libx86" "/LIBPATH:C:Program Files (x86)Windows Kits10lib10.0.19041.0ucrtx86" "/LIBPATH:C:Program Files (x86)Windows Kits10\lib10.0.19041.0\umx86" shout.lib /EXPORT:PyInit_shout buildtemp.win32-cpython-310Releaseshout.obj /OUT:buildlib.win32-cpython-310shout.cp310-win_amd64.pyd /IMPLIB:buildtemp.win32-cpython-310Releaseshout.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!!

Asked By: Chris P

||

Answers:

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

Answered By: Nadav Zingerman

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 = '[email protected]',
       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.

Answered By: Chris P

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 = 8000n')
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('stopn')
            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).

Answered By: Chris P
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.