首页 > 解决方案 > 在 windows 10 (python 版本 3.9) 中安装 python 喊模块

问题描述

我正在尝试在 Windows 10 中安装 python-shout 模块,但它失败了。在 ubuntu 中运行良好。

文件shout.c(修改)

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <shout/shout.h>

#define PyString_Check(m) PyUnicode_Check(m)
#define PyString_AsString(m) PyBytes_AS_STRING((PyObject*)PyUnicode_AsEncodedString(m, "utf-8", "ignore"))
#define PyInt_Check(m) PyLong_Check(m)
#define INITERROR return

static PyObject* ShoutError;



typedef struct {
    PyObject_HEAD
    shout_t* conn;
    PyObject* attr;
} ShoutObject;

typedef int(*pshout_set_shout)(shout_t*);
typedef int(*pshout_set_shout_int)(shout_t*, int);
typedef int(*pshout_set_shout_str)(shout_t*, const char*);

typedef struct _ShoutObjectAttr {
    const char* name;
    pshout_set_shout set_shout;
    int(*set)(struct _ShoutObjectAttr*, ShoutObject*, PyObject*);
} ShoutObjectAttr;

typedef struct {
    const char* name;
    int val;
} kv_strint;

/* -- module prototypes -- */
static PyObject* pshout_version(PyObject* self, PyObject* args);

/* -- ShoutObject instance prototypes -- */
static PyObject* pshoutobj_new(PyObject* self, PyObject* args);
static void pshoutobj_initattrs(PyObject* self);
static void pshoutobj_free(PyObject* self);
static PyObject* pshoutobj_getattr(PyObject* self, char* name);
static int pshoutobj_setattr(PyObject* self, char* name, PyObject* v);

static PyObject* pshoutobj_open(ShoutObject* self);
static PyObject* pshoutobj_close(ShoutObject* self);
static PyObject* pshoutobj_get_connected(ShoutObject* self);
static PyObject* pshoutobj_send(ShoutObject* self, PyObject* args);
static PyObject* pshoutobj_sync(ShoutObject* self);
static PyObject* pshoutobj_delay(ShoutObject* self);
static PyObject* pshoutobj_queuelen(ShoutObject* self);
static PyObject* pshoutobj_set_metadata(ShoutObject* self, PyObject* args);

/* -- attr prototypes -- */
static int pshoutobj_set_str(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v);
static int pshoutobj_set_int(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v);
static int pshoutobj_set_bool(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v);
static int pshoutobj_set_proto(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v);
static int pshoutobj_set_fmt(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v);
static int pshoutobj_set_audio_info(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v);

static char docstring[] = "Shout library v2 interface\n\n"
    "Use this module to send audio data to an icecast (or shoutcast) server\n"
    "shout.Shout() creates a new Shout object.\n\n"

    "Shout\n\n"
    "Use this object to send data to an icecast server.\n"
    "Set the connection attributes before calling \"open\" (at least\n"
    "\"host\", \"port\", \"password\" and \"mount\" must be specified).\n\n"
    "Methods:\n"
    "            open() - connect to server\n"
    "   get_connected() - monitor connection status in nonblocking mode\n"
    "           close() - disconnect from server\n"
    "        send(data) - send audio data to server\n"
    "            sync() - sleep until server needs more data. This is equal to\n"
    "                     the time it takes to play data sent since last sync\n"
    "           delay() - return milliseconds to wait before sending more data\n"
    "        queuelen() - return number of bytes on the nonblocking write queue\n"
    "set_metadata(dict) - update stream metadata on server (current known key is\n"
    "                     \"song\". Not currently supported for ogg.\n\n"
    "Attributes:\n"
    "       host - name or address of destination server\n"
    "       port - port of destination server\n"
    "       user - source user name (optional)\n"
    "   password - source password\n"
    "      mount - mount point on server (relative URL, eg \"/stream.ogg\")\n"
    "   protocol - server protocol: \"http\" (the default) for icecast 2,\n"
    "              \"xaudiocast\" for icecast 1, or \"icy\" for shoutcast\n"
    "nonblocking - use nonblocking send\n"
    "     format - audio format: \"ogg\" (the default) or \"mp3\"\n"
    "       name - stream name\n"
    "        url - stream web page\n"
    "      genre - stream genre\n"
    "description - longer stream description\n"
    " audio_info - dictionary of stream audio parameters, for YP information.\n"
    "              Useful keys include \"bitrate\" (in kbps), \"samplerate\"\n"
    "              (in Hz), \"channels\" and \"quality\" (Ogg encoding\n"
    "              quality). All dictionary values should be strings. The known\n"
    "              keys are defined as the SHOUT_AI_* constants, but any other\n"
    "              will be passed along to the server as well.\n"
    "   dumpfile - file name to record stream to on server (not supported on\n"
    "              all servers)\n"
    "      agent - for customizing the HTTP user-agent header\n\n";
    
static ShoutObjectAttr ShoutObjectAttrs[] = {
    { "host",        (pshout_set_shout)shout_set_host, pshoutobj_set_str },
    { "port",        (pshout_set_shout)shout_set_port, pshoutobj_set_int },
    { "user",        (pshout_set_shout)shout_set_user, pshoutobj_set_str },
    { "password",    (pshout_set_shout)shout_set_password, pshoutobj_set_str },
    { "agent",       (pshout_set_shout)shout_set_agent, pshoutobj_set_str },
    { "format",      (pshout_set_shout)shout_set_format, pshoutobj_set_fmt },
    { "protocol",    (pshout_set_shout)shout_set_protocol, pshoutobj_set_proto },
    { "nonblocking", (pshout_set_shout)shout_set_nonblocking, pshoutobj_set_bool },
    { "mount",       (pshout_set_shout)shout_set_mount, pshoutobj_set_str },
    { "name",        (pshout_set_shout)shout_set_name, pshoutobj_set_str },
    { "url",         (pshout_set_shout)shout_set_url, pshoutobj_set_str },
    { "genre",       (pshout_set_shout)shout_set_genre, pshoutobj_set_str },
    { "description", (pshout_set_shout)shout_set_description, pshoutobj_set_str },
    { "public",      (pshout_set_shout)shout_set_public, pshoutobj_set_int },
    { "dumpfile",    (pshout_set_shout)shout_set_dumpfile, pshoutobj_set_str },
    { "audio_info",  NULL, pshoutobj_set_audio_info },
    { NULL, NULL, NULL }
};


static kv_strint ShoutFormatMap[] = {
    { "ogg",    SHOUT_FORMAT_OGG },
    { "mp3",    SHOUT_FORMAT_MP3 },
    { "vorbis", SHOUT_FORMAT_OGG }, /* for backwards compatibility */
    { "webm",   SHOUT_FORMAT_WEBM },
    { NULL, 0 }
};

static int pshoutobj_set_fmt(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v) {
    const char* val;
    kv_strint* fmt_map;
    pshout_set_shout_int set_shout;

    if (!PyString_Check(v)) {
        PyErr_SetString(PyExc_TypeError, "String argument required");
        return SHOUTERR_INSANE;
    }

    val = PyString_AsString(v);
    for (fmt_map = ShoutFormatMap; fmt_map->name; fmt_map++) {
        if (!strcmp(fmt_map->name, val)) {
            set_shout = (pshout_set_shout_int)attr->set_shout;
            return set_shout(self->conn, fmt_map->val);
        }
    }

    PyErr_SetString(ShoutError, "Unsupported format");
    return SHOUTERR_UNSUPPORTED;
}
    
static kv_strint ShoutProtocolMap[] = {
    { "http",       SHOUT_PROTOCOL_HTTP },
    { "xaudiocast", SHOUT_PROTOCOL_XAUDIOCAST },
    { "icy",        SHOUT_PROTOCOL_ICY },
    { NULL, 0 }
};



static int pshoutobj_setattr(PyObject* self, char* name, PyObject* v) {
    ShoutObject* me = (ShoutObject*)self;
    ShoutObjectAttr* attr;

    if (!me->attr && !(me->attr = PyDict_New()))
        return -1;

    if (v == NULL)
        return -1;
  
    for (attr = ShoutObjectAttrs; attr->name; attr++) {
        if (!strcmp(attr->name, name)) {
            if (v != Py_None && attr->set(attr, me, v) != SHOUTERR_SUCCESS) {
                if (!PyErr_Occurred())
                    PyErr_SetString(ShoutError, shout_get_error(me->conn));
                return -1;
            }
            break;
        }
    }
    return PyDict_SetItemString(me->attr, name, v);
}


static PyObject* pshout_version(PyObject* self, PyObject* args) {
    if (!PyArg_ParseTuple(args, ""))
        return NULL;

    return Py_BuildValue("s", shout_version(NULL, NULL, NULL));
}

static PyObject* pshoutobj_open(ShoutObject* self) {
    int ret;
    Py_BEGIN_ALLOW_THREADS
    ret=shout_open(self->conn);
    Py_END_ALLOW_THREADS
    if (!((ret == SHOUTERR_SUCCESS)||((ret==SHOUTERR_BUSY) && shout_get_nonblocking(self->conn)))) {
        PyErr_SetString(ShoutError, shout_get_error(self->conn));
        return NULL;
    }
    return Py_BuildValue("i", 1);
}

static PyObject* pshoutobj_close(ShoutObject* self) {
    if (shout_close(self->conn) != SHOUTERR_SUCCESS) {
        PyErr_SetString(ShoutError, shout_get_error(self->conn));
        return NULL;
    }
    return Py_BuildValue("i", 1);
}

static PyObject* pshoutobj_get_connected(ShoutObject* self) {
    return Py_BuildValue("i", shout_get_connected(self->conn));
}

static PyObject* pshoutobj_set_metadata(ShoutObject* self, PyObject* args) {
    shout_metadata_t* metadata;
    PyObject* dict;
    PyObject* key;
    PyObject* val;
    const char* skey;
    const char* sval;
    Py_ssize_t i = 0;
    int rc;

    if (!(metadata = shout_metadata_new())) {
        PyErr_NoMemory();
        return NULL;
    }

    if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict))
        return NULL;

    while (PyDict_Next(dict, &i, &key, &val)) {
        if (!PyString_Check(key)) {
            PyErr_SetString(PyExc_TypeError, "Dictionary key must be string");
            shout_metadata_free(metadata);
            return NULL;
        }
        if (!PyString_Check(val)) {
            PyErr_SetString(PyExc_TypeError, "Dictionary value must be string");
            shout_metadata_free(metadata);
            return NULL;
        }

        skey = PyString_AsString(key);
        sval = PyString_AsString(val);

        if ((rc = shout_metadata_add(metadata, skey, sval)) != SHOUTERR_SUCCESS) {
            if (rc == SHOUTERR_MALLOC)
                PyErr_NoMemory();
            else if (rc == SHOUTERR_INSANE)
                PyErr_SetString(PyExc_TypeError, "Dictionary key must not be empty");
            shout_metadata_free(metadata);
            return NULL;
        }
    }

    Py_BEGIN_ALLOW_THREADS
    rc = shout_set_metadata(self->conn, metadata);
    Py_END_ALLOW_THREADS
    shout_metadata_free(metadata);

    if (rc != SHOUTERR_SUCCESS) {
        PyErr_SetString(ShoutError, "Metadata not supported in this connection");
        return NULL;
    }

    return Py_BuildValue("i", 1);
}


static PyObject* pshoutobj_send(ShoutObject* self, PyObject* args) {
    const unsigned char* data;
    Py_ssize_t len;
    int res;

    if (!PyArg_ParseTuple(args, "y#", &data, &len))
        return NULL;

    Py_BEGIN_ALLOW_THREADS
    res = shout_send(self->conn, data, len);
    Py_END_ALLOW_THREADS

    if (res != SHOUTERR_SUCCESS) { 
        PyErr_SetString(ShoutError, shout_get_error(self->conn));
        return NULL;
    }
    return Py_BuildValue("i", 1);
}

static PyObject* pshoutobj_queuelen(ShoutObject* self) {
    return Py_BuildValue("i", shout_queuelen(self->conn));
}

static void pshoutobj_free(PyObject* self) {
    ShoutObject* me = (ShoutObject*)self;

    Py_XDECREF(me->attr);
    shout_free(me->conn);
    PyObject_Del(self);
}

static PyObject* pshoutobj_sync(ShoutObject* self) {
    Py_BEGIN_ALLOW_THREADS
    shout_sync(self->conn);
    Py_END_ALLOW_THREADS

    return Py_BuildValue("i", 1);
}

static PyObject* pshoutobj_delay(ShoutObject* self) {
    return Py_BuildValue("i", shout_delay(self->conn));
}

static PyObject* pshoutobj_getattr(PyObject* self, char* name) {
    ShoutObject* me = (ShoutObject*)self;

    if (!me->attr)
        pshoutobj_initattrs(self);

    if (me->attr) {
        PyObject* v = PyDict_GetItemString(me->attr, name);
        if (v) {
            Py_INCREF(v);
            return v;
        }
    }

    PyObject *nameobj = PyUnicode_FromString(name);
    return PyObject_GenericGetAttr((PyObject*)self, nameobj);
}

static void pshoutobj_initattrs(PyObject* self) {
    shout_t* conn = ((ShoutObject*)self)->conn;
    int val, i;

    pshoutobj_setattr(self, "host", Py_BuildValue("s", shout_get_host(conn)));
    pshoutobj_setattr(self, "port", Py_BuildValue("i", shout_get_port(conn)));
    pshoutobj_setattr(self, "user", Py_BuildValue("s", shout_get_user(conn)));
    pshoutobj_setattr(self, "password", Py_BuildValue(""));
    pshoutobj_setattr(self, "mount", Py_BuildValue(""));
    pshoutobj_setattr(self, "name", Py_BuildValue(""));
    pshoutobj_setattr(self, "url", Py_BuildValue(""));
    pshoutobj_setattr(self, "genre", Py_BuildValue(""));
    pshoutobj_setattr(self, "description", Py_BuildValue(""));
    pshoutobj_setattr(self, "audio_info", Py_BuildValue(""));
    pshoutobj_setattr(self, "dumpfile", Py_BuildValue(""));  
    pshoutobj_setattr(self, "agent", Py_BuildValue("s", shout_get_agent(conn)));
    pshoutobj_setattr(self, "protocol", Py_BuildValue(""));
    pshoutobj_setattr(self, "nonblocking", shout_get_nonblocking(conn) ? Py_True : Py_False);
    pshoutobj_setattr(self, "format", Py_BuildValue(""));

    val = shout_get_protocol(conn);
    for (i = 0; ShoutProtocolMap[i].name; i++)
        if (ShoutProtocolMap[i].val == val) {
            pshoutobj_setattr(self, "protocol", Py_BuildValue("s", ShoutProtocolMap[i].name));
            break;
        }

    val = shout_get_format(conn);
    for (i = 0; ShoutFormatMap[i].name; i++)
        if (ShoutFormatMap[i].val == val) {
            pshoutobj_setattr(self, "format", Py_BuildValue("s", ShoutFormatMap[i].name));
            break;
        }
}








static PyMethodDef ShoutObjectMethods[] = {
    { "open", (PyCFunction)pshoutobj_open, METH_NOARGS,
    "Connect to server." },
    { "close", (PyCFunction)pshoutobj_close, METH_NOARGS,
    "Close connection to server." },
    { "get_connected", (PyCFunction)pshoutobj_get_connected, METH_NOARGS,
    "Check for connection progress." },
    { "send", (PyCFunction)pshoutobj_send, METH_VARARGS,
    "Send data to server." },
    { "sync", (PyCFunction)pshoutobj_sync, METH_NOARGS,
    "Sleep for time required to play previously sent data." },
    { "delay", (PyCFunction)pshoutobj_delay, METH_NOARGS,
    "Return amount of time in milliseconds to wait before sending more data." },
    { "queuelen", (PyCFunction)pshoutobj_queuelen, METH_NOARGS,
    "Return the number of bytes currently on the write queue for nonblocking send" },
    { "set_metadata", (PyCFunction)pshoutobj_set_metadata, METH_VARARGS,
    "Update stream metadata on server (takes a dictionary argument. Current keys are: \"song\"" },

    /* attributes (cribbed from Arc's ogg-python technique) */
    { "host", NULL, METH_NOARGS, NULL },
    { "port", NULL, METH_NOARGS, NULL },
    { "user", NULL, METH_NOARGS, NULL },
    { "password", NULL, METH_NOARGS, NULL },
    { "agent", NULL, METH_NOARGS, NULL },
    { "format", NULL, METH_NOARGS, NULL },
    { "protocol", NULL, METH_NOARGS, NULL },
    { "nonblocking", NULL, METH_NOARGS, NULL },
    { "mount", NULL, METH_NOARGS, NULL },
    { "name", NULL, METH_NOARGS, NULL },
    { "url", NULL, METH_NOARGS, NULL },
    { "genre", NULL, METH_NOARGS, NULL },
    { "description", NULL, METH_NOARGS, NULL },
    { "public", NULL, METH_NOARGS, NULL },
    { "dumpfile", NULL, METH_NOARGS, NULL },
    { "audio_info", NULL, METH_NOARGS, NULL },

    /* sentinel */
    { NULL, NULL, 0, NULL }
};

static PyTypeObject ShoutObject_Type = {
    {PyObject_HEAD_INIT(NULL)},
    "shout.Shout",                           /* tp_name */
    sizeof(ShoutObject),                     /* tp_basicsize */
    0,                                       /* tp_itemsize */
    pshoutobj_free,                          /* tp_dealloc */
    0,                                       /* tp_print */
    pshoutobj_getattr,                       /* tp_getattr */
    pshoutobj_setattr,                       /* tp_setattr */
    0,                                       /* tp_reserved */
    0,                                       /* tp_repr */
    0,                                       /* tp_as_number */
    0,                                       /* tp_as_sequence */
    0,                                       /* tp_as_mapping */
    0,                                       /* tp_hash */
    0,                                       /* tp_call */
    0,                                       /* tp_str */
    0,                                       /* tp_getattro */
    0,                                       /* tp_setattro */
    0,                                       /* tp_as_buffer */
    0,                                       /* tp_flags */
    "See shout module help: help(shout)\n",  /* tp_doc */
    0,                                       /* tp_traverse */
    0,                                       /* tp_clear */
    0,                                       /* tp_richcompare */
    0,                                       /* tp_weaklistoffset */
    0,                                       /* tp_iter */
    0,                                       /* tp_iternext */
    ShoutObjectMethods                       /* tp_methods */
};

static PyObject* pshoutobj_new(PyObject* self, PyObject* args) {
    ShoutObject* me;

    if (!PyArg_ParseTuple(args, ""))
        return NULL;

    if (!(me = PyObject_New(ShoutObject, &ShoutObject_Type)))
        return NULL;

    me->attr = NULL;

    if (!(me->conn = shout_new())) {
        PyErr_NoMemory();
        PyObject_Del(self);

    return NULL;
    }

    return (PyObject*)me;
}

static PyMethodDef ShoutMethods[] = {
    { "version", pshout_version, METH_VARARGS,
    "Return the version of libshout being used, as a string." },
    { "Shout", pshoutobj_new, METH_VARARGS,
    "Create a new Shout object." },
    { NULL, NULL, 0, NULL }
};

static int pshoutobj_set_str(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v) {
    const char* str;
    pshout_set_shout_str set_shout;

    if (!PyString_Check(v)) {
        PyErr_SetString(PyExc_TypeError, "String argument required");
        return -1;
    }

    str = PyString_AsString(v);
    set_shout = (pshout_set_shout_str)attr->set_shout;
    return set_shout(self->conn, str);
}


static int pshoutobj_set_proto(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v) {
    const char* val;
    kv_strint* proto_map;
    pshout_set_shout_int set_shout;

    if (!PyString_Check(v)) {
        PyErr_SetString(PyExc_TypeError, "String argument required");
        return SHOUTERR_INSANE;
    }

    val = PyString_AsString(v);
    for (proto_map = ShoutProtocolMap; proto_map->name; proto_map++) {
        if (!strcmp(proto_map->name, val)) {
            set_shout = (pshout_set_shout_int)attr->set_shout;
            return set_shout(self->conn, proto_map->val);
        }
    }

    PyErr_SetString(ShoutError, "Unsupported protocol");
    return SHOUTERR_UNSUPPORTED;
}

static int pshoutobj_set_audio_info(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v) {
    PyObject* key;
    PyObject* val;
    const char* skey;
    const char* sval;
    Py_ssize_t i = 0;
    int rc;

    if (!PyDict_Check(v)) {
        PyErr_SetString(PyExc_TypeError, "Dictionary argument required");
        return SHOUTERR_INSANE;
    }

    while (PyDict_Next(v, &i, &key, &val)) {
        if (!PyString_Check(key)) {
            PyErr_SetString(PyExc_TypeError, "Dictionary key must be string");
            return SHOUTERR_INSANE;
        }
        if (!PyString_Check(val)) {
            PyErr_SetString(PyExc_TypeError, "Dictionary value must be string");
            return SHOUTERR_INSANE;
        }

        skey = PyString_AsString(key);
        sval = PyString_AsString(val);

        Py_BEGIN_ALLOW_THREADS
        rc = shout_set_audio_info(self->conn, skey, sval);
        Py_END_ALLOW_THREADS

        if (rc != SHOUTERR_SUCCESS)
            return rc;
    }

    return SHOUTERR_SUCCESS;
}

static int pshoutobj_set_bool(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v) {
    long val;
    pshout_set_shout_int set_shout;

    if (!PyBool_Check(v)) {
        PyErr_SetString(PyExc_TypeError, "Boolean argument required");
        return -1;
    }

    val = (v == Py_True) ? 1 : 0;
    set_shout = (pshout_set_shout_int)attr->set_shout;
    return set_shout(self->conn, val);
}

static int pshoutobj_set_int(ShoutObjectAttr* attr, ShoutObject* self, PyObject* v) {
    long val;
    pshout_set_shout_int set_shout;

    if (!PyInt_Check(v)) {
        PyErr_SetString(PyExc_TypeError, "Numerical argument required");
        return -1;
    }

    val = PyLong_AsLong(v);
    set_shout = (pshout_set_shout_int)attr->set_shout;
    return set_shout(self->conn, val);
}


//static struct PyModuleDef shout = 
//{
//  PyModuleDef_HEAD_INIT,
//  "shout", /* name of module */
//  docstring,          /* module documentation, may be NULL */
//  -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
//  ShoutMethods
//};


static struct PyModuleDef shoutmodule = {
    PyModuleDef_HEAD_INIT,
    "shout",
    "Connects to icecast 2, icecast 1 and shoutcast radio servers",
    -1,
    ShoutMethods
};

PyMODINIT_FUNC PyInit_shout(void){
    PyObject* module;
    PyObject* dict;
    
    Py_TYPE(&ShoutObject_Type) = &PyType_Type;

    module = PyModule_Create(&shoutmodule);

    /*
    if (module == NULL)
        INITERROR;
    */

    ShoutError = PyErr_NewException("shout.ShoutException", NULL, NULL);
    if (ShoutError == NULL) {
        Py_DECREF(module);
        //INITERROR;
    }

    dict = PyModule_GetDict(module);
    PyDict_SetItemString(dict, "ShoutException", ShoutError);

    PyModule_AddIntConstant(module, "SHOUTERR_SUCCESS", SHOUTERR_SUCCESS);
    PyModule_AddIntConstant(module, "SHOUTERR_INSANE", SHOUTERR_INSANE);
    PyModule_AddIntConstant(module, "SHOUTERR_NOCONNECT", SHOUTERR_NOCONNECT);
    PyModule_AddIntConstant(module, "SHOUTERR_NOLOGIN", SHOUTERR_NOLOGIN);
    PyModule_AddIntConstant(module, "SHOUTERR_SOCKET", SHOUTERR_SOCKET);
    PyModule_AddIntConstant(module, "SHOUTERR_MALLOC", SHOUTERR_MALLOC);
    PyModule_AddIntConstant(module, "SHOUTERR_METADATA", SHOUTERR_METADATA);
    PyModule_AddIntConstant(module, "SHOUTERR_CONNECTED", SHOUTERR_CONNECTED);
    PyModule_AddIntConstant(module, "SHOUTERR_UNCONNECTED", SHOUTERR_UNCONNECTED);
    PyModule_AddIntConstant(module, "SHOUTERR_UNSUPPORTED", SHOUTERR_UNSUPPORTED);
    PyModule_AddIntConstant(module, "SHOUTERR_BUSY", SHOUTERR_BUSY);

    PyModule_AddStringConstant(module, "SHOUT_AI_BITRATE", SHOUT_AI_BITRATE);
    PyModule_AddStringConstant(module, "SHOUT_AI_SAMPLERATE", SHOUT_AI_SAMPLERATE);
    PyModule_AddStringConstant(module, "SHOUT_AI_CHANNELS", SHOUT_AI_CHANNELS);
    PyModule_AddStringConstant(module, "SHOUT_AI_QUALITY", SHOUT_AI_QUALITY);

    return module;
};

文件 setup.py(修改)

# distutils build script
# To install shout-python, run 'python setup.py install'

from distutils.core import setup, Extension

shout = Extension('shout',
                    include_dirs = ['C:\\Python\\include','C:\\Users\\Χρήστος\\Documents\\python-shout\\include','C:\\Users\\Χρήστος\\Documents\\python-shout\\lib','C:\\Users\\Χρήστος\\Documents\\python-shout\\bin'],
                    library_dirs = ['C:\\Python\\include','C:\\Users\\Χρήστος\\Documents\\python-shout\\include','C:\\Users\\Χρήστος\\Documents\\python-shout\\lib','C:\\Users\\Χρήστος\\Documents\\python-shout\\bin'],
                    sources = ['shout.c'])

setup (name = 'shout',
       version = '0.2.7',
       description = 'Connects to shoutcast, icecast1 and icecast2 radio servers',
       author = 'Brendan Cully',
       author_email = 'brendan@xiph.org',
       url = 'http://icecast.org/download.php',
       ext_modules = [shout])

的命令输出python setup.py install

C:\Users\Χρήστος\Documents\python-shout\python-shout>python setup.py install
running install
running build
running build_ext
building 'shout' extension
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29910\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Python\include -IC:\Users\Χρήστος\Documents\python-shout\include -IC:\Users\Χρήστος\Documents\python-shout\lib -IC:\Users\Χρήστος\Documents\python-shout\bin -IC:\Python\include -IC:\Python\include -IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29910\include -IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um -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\shared -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\winrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt /Tcshout.c /Fobuild\temp.win-amd64-3.9\Release\shout.obj
shout.c
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29910\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Python\include /LIBPATH:C:\Users\Χρήστος\Documents\python-shout\include /LIBPATH:C:\Users\Χρήστος\Documents\python-shout\lib /LIBPATH:C:\Users\Χρήστος\Documents\python-shout\bin /LIBPATH:C:\Python\libs /LIBPATH:C:\Python\PCbuild\amd64 /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29910\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64 /EXPORT:PyInit_shout build\temp.win-amd64-3.9\Release\shout.obj /OUT:build\lib.win-amd64-3.9\shout.cp39-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.9\Release\shout.cp39-win_amd64.lib
   Creating library build\temp.win-amd64-3.9\Release\shout.cp39-win_amd64.lib and object build\temp.win-amd64-3.9\Release\shout.cp39-win_amd64.exp
shout.obj : error LNK2001: unresolved external symbol shout_sync
shout.obj : error LNK2001: unresolved external symbol shout_send
...
shout.obj : error LNK2001: unresolved external symbol shout_set_nonblocking
shout.obj : error LNK2001: unresolved external symbol shout_set_description
build\lib.win-amd64-3.9\shout.cp39-win_amd64.pyd : fatal error LNK1120: 38 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29910\\bin\\HostX86\\x64\\link.exe' failed with exit code 1120

编辑:我在 msys 控制台(https://packages.msys2.org/package/mingw-w64-i686-libshout?repo=mingw32)中成功安装了 libshout 但 pip install python-shout 失败。

如何在 Windows 10(python 3.9)中安装 python-shout?

标签: pythoninstallationpip

解决方案


我已经成功安装了带有 MingGW 和 MSYS 2 的 python-shout 模块。

指示:

  1. 从https://repo.msys2.org/distrib/x86_64/msys2-x86_64-20210228.exe下载 msys2

  2. 运行安装程序(说明:https ://www.msys2.org/ )

  3. pacman -Syu使用和更新包pacman -Su

  4. 为 msys2 安装基本程序pacman -S --needed base-devel mingw-w64-x86_64-toolchain

  5. 安装蟒蛇pacman -S mingw-w64-x86_64-python

  6. 安装 libshoutpacman -S mingw-w64-x86_64-libshout

  7. 从: https ://github.com/yomguy/python-shout下载并提取 python-shout

  8. 编辑 setup.py 如下:

从 setuptools 导入设置,扩展
导入操作系统
导入系统
导入设置工具

版本 = '0.2.7'

使用 open("README.md", "r") 作为 fh:
    long_description = fh.read()

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

# 必须有更简单的方法来设置这些标志!
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=[]
# 库=[]
# runtime_library_dirs=[]
# extra_objects,extra_compile_args,extra_link_args
喊=扩展('喊',来源= ['shout.c'],
                  include_dirs = iflags,
                  extra_compile_args = extra_cflags,
                  library_dirs = libdirs,
                  库 = libsonly)

# 数据文件 = []
设置(名称='python-shout',
       版本 = 版本,
       description = 'libshout 2 的绑定',
       long_description=long_description,
       long_description_content_type="文本/降价",
       url = 'http://icecast.org/download.php',
       作者 = '布伦丹·库利',
       author_email = 'brendan@xiph.org',
       ext_modules = [喊],
       包=setuptools.find_packages(),
       分类器=[
                   "编程语言 :: Python :: 3",
                   "编程语言 :: Python :: 2",
                   “许可证 :: OSI 批准 :: GNU 通用公共许可证 v2 (GPLv2)”,
                   “操作系统 :: 独立于操作系统”,
               ],

       )
  1. 安装安装工具pacman -S python-setuptools

  2. 安装 python-shout 运行: 10.acd c/Users/Χρήστος/Desktop/python-shout-master 请注意,您必须输入您的 Windows 用户名而不是我的 (Χρήστος) 和 10.bpython setup.py install

就是这样。Python-shout 模块已成功安装在您的 Windows 机器中。要测试它,只需运行:

Python
>>进口喊话
>>s = 喊。喊()
>>print("使用 libshout 版本 %s" %shout.version())

之后,您可以在 MSYS2 控制台 ( https://github.com/pyinstaller/pyinstaller ) 中从源代码安装 pyinstaller 下载并解压,然后运行 ​​python setup.py install

最后运行 pyinstaller --onefile icecast_program.py

然后您将拥有一个可以在每个 Windows 系统中运行的 exe。


推荐阅读