def playback_data(self, data, num_samples, format, pending):
    global pending_data

    # Make sure we don't pass incomplete frames to alsa
    num_samples -= num_samples % CHANNELS

    buf = pending_data + ffi.buffer(data, num_samples * SAMPLESIZE)[:]

    try:
        total = 0
        while len(buf) >= PERIODSIZE * CHANNELS * SAMPLESIZE:
            audio_queue.put(buf[:PERIODSIZE * CHANNELS * SAMPLESIZE], block=False)
            buf = buf[PERIODSIZE * CHANNELS * SAMPLESIZE:]
            total += PERIODSIZE * CHANNELS

        pending_data = buf
        return num_samples
    except Queue.Full:
        return total
    finally:
        pending[0] = audio_queue.qsize() * PERIODSIZE * CHANNELS
def playback_data(self, data, num_samples, format, pending):
    global pending_data

    # Make sure we don't pass incomplete frames to alsa
    num_samples -= num_samples % CHANNELS

    buf = pending_data + ffi.buffer(data, num_samples * SAMPLESIZE)[:]

    try:
        total = 0
        while len(buf) >= PERIODSIZE * CHANNELS * SAMPLESIZE:
            audio_queue.put(buf[:PERIODSIZE * CHANNELS * SAMPLESIZE], block=False)
            buf = buf[PERIODSIZE * CHANNELS * SAMPLESIZE:]
            total += PERIODSIZE * CHANNELS

        pending_data = buf
        return num_samples
    except Queue.Full:
        return total
    finally:
        pending[0] = audio_queue.qsize() * PERIODSIZE * CHANNELS
def playback_data(self, data, num_samples, format, pending):
    global pending_data
    
    play_event.set()
    
    # Make sure we don't pass incomplete frames to alsa
    num_samples -= num_samples % CHANNELS

    buf = pending_data + ffi.buffer(data, num_samples * SAMPLESIZE)[:]

    try:
        total = 0
        while len(buf) >= PERIODSIZE * CHANNELS * SAMPLESIZE:
            audio_player.write(buf[:PERIODSIZE * CHANNELS * SAMPLESIZE])
            buf = buf[PERIODSIZE * CHANNELS * SAMPLESIZE:]
            total += PERIODSIZE * CHANNELS

        pending_data = buf
        return num_samples
    except player.BufferFull:
        return total
    finally:
        pending[0] = audio_player.buffer_length() * PERIODSIZE * CHANNELS
Пример #4
0
    def __init__(self, error_cb = error_callback):
        pass_required = False
        if __name__ == "__main__":
            #Require username and password when used without a web server
            pass_required = True
        arg_parser = argparse.ArgumentParser(description='Web interface for Spotify Connect', parents=[audio_arg_parser])
        arg_parser.add_argument('--debug', '-d', help='enable libspotify_embedded/flask debug output', action="store_true")
        arg_parser.add_argument('--key', '-k', help='path to spotify_appkey.key', default='spotify_appkey.key', type=file)
        arg_parser.add_argument('--username', '-u', help='your spotify username', required=pass_required)
        arg_parser.add_argument('--password', '-p', help='your spotify password', required=pass_required)
        arg_parser.add_argument('--name', '-n', help='name that shows up in the spotify client', default='TestConnect')
        arg_parser.add_argument('--bitrate', '-b', help='Sets bitrate of audio stream (may not actually work)', choices=[90, 160, 320], type=int, default=160)
        arg_parser.add_argument('--credentials', '-c', help='File to load and save credentials from/to', default='credentials.json')
        self.args = arg_parser.parse_args()

        app_key = ffi.new('uint8_t *')
        self.args.key.readinto(ffi.buffer(app_key))
        app_key_size = len(self.args.key.read()) + 1

        self.credentials = dict({
            'device-id': str(uuid.uuid4()),
            'username': None,
            'blob': None
        })

        try:
            with open(self.args.credentials) as f:
                self.credentials.update(
                        { k: v.encode('utf-8') if isinstance(v, unicode) else v
                            for (k,v)
                            in json.loads(f.read()).iteritems() })
        except IOError:
            pass

        if self.args.username:
            self.credentials['username'] = self.args.username

        userdata = ffi.new_handle(self)

        self.config = {
             'version': 4,
             'buffer': C.malloc(0x100000),
             'buffer_size': 0x100000,
             'app_key': app_key,
             'app_key_size': app_key_size,
             'deviceId': ffi.new('char[]', self.credentials['device-id']),
             'remoteName': ffi.new('char[]', self.args.name),
             'brandName': ffi.new('char[]', 'DummyBrand'),
             'modelName': ffi.new('char[]', 'DummyModel'),
             'deviceType': lib.kSpDeviceTypeAudioDongle,
             'error_callback': error_cb,
             'userdata': userdata,
        }

        init = ffi.new('SpConfig *' , self.config)
        print "SpInit: {}".format(lib.SpInit(init))

        lib.SpRegisterConnectionCallbacks(connection_callbacks, userdata)
        if self.args.debug:
            lib.SpRegisterDebugCallbacks(debug_callbacks, userdata)
        lib.SpRegisterPlaybackCallbacks(playback_callbacks, userdata)

        mixer_volume = int(mixer.getvolume()[0] * 655.35)
        lib.SpPlaybackUpdateVolume(mixer_volume)

        bitrates = {
            90: lib.kSpBitrate90k,
            160: lib.kSpBitrate160k,
            320: lib.kSpBitrate320k
        }

        lib.SpPlaybackSetBitrate(bitrates[self.args.bitrate])

        playback_setup()

        print_zeroconf_vars()

        if self.credentials['username'] and self.args.password:
            self.login(password=self.args.password)
        elif self.credentials['username'] and self.credentials['blob']:
            self.login(blob=self.credentials['blob'])
Пример #5
0
    def __init__(self, error_cb=error_callback, web_arg_parser=None):
        arg_parsers = [audio_arg_parser]
        if web_arg_parser:
            arg_parsers.append(web_arg_parser)
        arg_parser = argparse.ArgumentParser(
            description="Deamon Spotify Connect", parents=arg_parsers)
        arg_parser.add_argument(
            "--debug",
            "-d",
            help="enable libspotify_embedded debug output",
            action="store_true",
        )
        arg_parser.add_argument(
            "--key",
            "-k",
            help=
            "path to spotify_appkey.key (can be obtained from https://developer.spotify.com/my-account/keys )",
            default="spotify_appkey.key",
        )
        arg_parser.add_argument("--username",
                                "-u",
                                help="your spotify username")
        arg_parser.add_argument("--password",
                                "-p",
                                help="your spotify password")
        arg_parser.add_argument(
            "--name",
            "-n",
            help="name that shows up in the spotify client",
            default="TestConnect",
        )
        arg_parser.add_argument(
            "--bitrate",
            "-b",
            help="Sets bitrate of audio stream (may not actually work)",
            choices=[90, 160, 320],
            type=int,
            default=160,
        )
        arg_parser.add_argument(
            "--credentials",
            "-c",
            help="File to load and save credentials from/to",
            default="credentials.json",
        )
        self.args = arg_parser.parse_args()

        print("Using libspotify_embedded version: {}".format(
            ffi.string(lib.SpGetLibraryVersion())))

        try:
            with open(self.args.key, "rb") as f:
                app_key = ffi.new("uint8_t *")
                f.readinto(ffi.buffer(app_key))
                app_key_size = len(f.read()) + 1
        except IOError as e:
            print("Error opening app key: {}.".format(e))
            print(
                "If you don't have one, it can be obtained from https://developer.spotify.com/my-account/keys"
            )
            sys.exit(1)

        self.credentials = dict({
            "device-id": str(uuid.uuid4()),
            "username": None,
            "blob": None
        })

        try:
            with open(self.args.credentials) as f:
                self.credentials.update(json.loads(f.read()).items())

        except IOError:
            pass

        if self.args.username:
            self.credentials["username"] = self.args.username

        userdata = ffi.new_handle(self)

        if self.args.debug:
            lib.SpRegisterDebugCallbacks(debug_callbacks, userdata)

        self.config = {
            "version": 4,
            "buffer": C.malloc(0x100000),
            "buffer_size": 0x100000,
            "app_key": app_key,
            "app_key_size": app_key_size,
            "deviceId": ffi.new("char[]",
                                self.credentials["device-id"].encode()),
            "remoteName": ffi.new("char[]", self.args.name.encode()),
            "brandName": ffi.new("char[]", "DummyBrand".encode()),
            "modelName": ffi.new("char[]", "DummyModel".encode()),
            "client_id": ffi.new("char[]", "0".encode()),
            "deviceType": lib.kSpDeviceTypeAudioDongle,
            "error_callback": error_cb,
            "userdata": userdata,
        }

        init = ffi.new("SpConfig *", self.config)
        init_status = lib.SpInit(init)
        print("SpInit: {}".format(init_status))
        if init_status != 0:
            print("SpInit failed, exiting")
            sys.exit(1)

        lib.SpRegisterConnectionCallbacks(connection_callbacks, userdata)
        lib.SpRegisterPlaybackCallbacks(playback_callbacks, userdata)

        mixer_volume = int(mixer.getvolume()[0] * 655.35)
        lib.SpPlaybackUpdateVolume(mixer_volume)

        bitrates = {
            90: lib.kSpBitrate90k,
            160: lib.kSpBitrate160k,
            320: lib.kSpBitrate320k,
        }

        lib.SpPlaybackSetBitrate(bitrates[self.args.bitrate])

        playback_setup()

        if self.credentials["username"] and self.args.password:
            self.login(password=self.args.password)
        elif self.credentials["username"] and self.credentials["blob"]:
            self.login(blob=self.credentials["blob"])
        else:
            raise ValueError("No username given, and none stored")
Пример #6
0
    def __init__(self, error_cb=error_callback, web_arg_parser=None):
        arg_parser = argparse.ArgumentParser(
            description='Web interface for Spotify Connect',
            parents=[audio_arg_parser])
        arg_parser.add_argument(
            '--debug',
            '-d',
            help='enable libspotify_embedded/flask debug output',
            action="store_true")
        arg_parser.add_argument(
            '--key',
            '-k',
            help=
            'path to spotify_appkey.key (can be obtained from https://developer.spotify.com/my-account/keys )',
            default='spotify_appkey.key')
        arg_parser.add_argument('--username',
                                '-u',
                                help='your spotify username')
        arg_parser.add_argument('--password',
                                '-p',
                                help='your spotify password')
        arg_parser.add_argument(
            '--name',
            '-n',
            help='name that shows up in the spotify client',
            default='TestConnect')
        arg_parser.add_argument(
            '--bitrate',
            '-b',
            help='Sets bitrate of audio stream (may not actually work)',
            choices=[90, 160, 320],
            type=int,
            default=160)
        arg_parser.add_argument(
            '--credentials',
            '-c',
            help='File to load and save credentials from/to',
            default='credentials.json')
        self.args = arg_parser.parse_args()

        print "Using libspotify_embedded version: {}".format(
            ffi.string(lib.SpGetLibraryVersion()))

        try:
            with open(self.args.key) as f:
                app_key = ffi.new('uint8_t *')
                f.readinto(ffi.buffer(app_key))
                app_key_size = len(f.read()) + 1
        except IOError as e:
            print "Error opening app key: {}.".format(e)
            print "If you don't have one, it can be obtained from https://developer.spotify.com/my-account/keys"
            sys.exit(1)

        self.credentials = dict({
            'device-id': str(uuid.uuid4()),
            'username': None,
            'blob': None
        })

        try:
            with open(self.args.credentials) as f:
                self.credentials.update({
                    k: v.encode('utf-8') if isinstance(v, unicode) else v
                    for (k, v) in json.loads(f.read()).iteritems()
                })
        except IOError:
            pass

        if self.args.username:
            self.credentials['username'] = self.args.username

        userdata = ffi.new_handle(self)

        if self.args.debug:
            lib.SpRegisterDebugCallbacks(debug_callbacks, userdata)

        self.config = {
            'version': 4,
            'buffer': C.malloc(0x100000),
            'buffer_size': 0x100000,
            'app_key': app_key,
            'app_key_size': app_key_size,
            'deviceId': ffi.new('char[]', self.credentials['device-id']),
            'remoteName': ffi.new('char[]', self.args.name),
            'brandName': ffi.new('char[]', 'DummyBrand'),
            'modelName': ffi.new('char[]', 'DummyModel'),
            'client_id': ffi.new('char[]', '0'),
            'deviceType': lib.kSpDeviceTypeAudioDongle,
            'error_callback': error_cb,
            'userdata': userdata,
        }

        init = ffi.new('SpConfig *', self.config)
        init_status = lib.SpInit(init)
        print "SpInit: {}".format(init_status)
        if init_status != 0:
            print "SpInit failed, exiting"
            sys.exit(1)

        lib.SpRegisterConnectionCallbacks(connection_callbacks, userdata)
        lib.SpRegisterPlaybackCallbacks(playback_callbacks, userdata)

        mixer_volume = int(mixer.getvolume()[0] * 655.35)
        lib.SpPlaybackUpdateVolume(mixer_volume)

        bitrates = {
            90: lib.kSpBitrate90k,
            160: lib.kSpBitrate160k,
            320: lib.kSpBitrate320k
        }

        lib.SpPlaybackSetBitrate(bitrates[self.args.bitrate])

        playback_setup()

        print_zeroconf_vars()

        if self.credentials['username'] and self.args.password:
            self.login(password=self.args.password)
        elif self.credentials['username'] and self.credentials['blob']:
            self.login(blob=self.credentials['blob'])
        else:
            if __name__ == '__main__':
                raise ValueError("No username given, and none stored")
Пример #7
0
    def __init__(self, error_cb=error_callback):
        pass_required = False
        if __name__ == "__main__":
            #Require username and password when used without a web server
            pass_required = True
        arg_parser = argparse.ArgumentParser(
            description='Web interface for Spotify Connect',
            parents=[mixer_arg_parser])
        arg_parser.add_argument(
            '--debug',
            '-d',
            help='enable libspotify_embedded/flask debug output',
            action="store_true")
        arg_parser.add_argument('--key',
                                '-k',
                                help='path to spotify_appkey.key',
                                default='spotify_appkey.key',
                                type=file)
        arg_parser.add_argument('--username',
                                '-u',
                                help='your spotify username',
                                required=pass_required)
        arg_parser.add_argument('--password',
                                '-p',
                                help='your spotify password',
                                required=pass_required)
        arg_parser.add_argument(
            '--name',
            '-n',
            help='name that shows up in the spotify client',
            default='TestConnect')
        arg_parser.add_argument(
            '--bitrate',
            '-b',
            help='Sets bitrate of audio stream (may not actually work)',
            choices=[90, 160, 320],
            type=int,
            default=160)
        self.args = arg_parser.parse_args()

        app_key = ffi.new('uint8_t *')
        self.args.key.readinto(ffi.buffer(app_key))
        app_key_size = len(self.args.key.read()) + 1

        self.init_vars = {
            'version': 4,
            'buffer': C.malloc(1048576),
            'buffer_size': 1048576,
            'os_device_id': ffi.new('char[]', 'abcdef-{}'.format(os.getpid())),
            'remoteName': ffi.new('char[]', self.args.name),
            'brandName': ffi.new('char[]', 'DummyBrand'),
            'modelName': ffi.new('char[]', 'DummyModel'),
            'deviceType': lib.kSpDeviceTypeAudioDongle,
            'error_callback': error_cb,
            'zero1': 0,
            'app_key': app_key,
            'app_key_size': app_key_size
        }

        init = ffi.new('struct init_data *', self.init_vars)

        print "SpInit: {}".format(lib.SpInit(init))

        lib.SpRegisterConnectionCallbacks(connection_callbacks, ffi.NULL)
        if self.args.debug:
            lib.SpRegisterDebugCallbacks(debug_callbacks, ffi.NULL)
        #lib.SpRegisterPlaybackCallbacks(playback_callbacks, ffi.NULL)
        lib.setup_audio_callbacks()

        mixer_volume = int(mixer.getvolume()[0] * 655.35)
        lib.SpPlaybackUpdateVolume(mixer_volume)

        bitrates = {
            90: lib.kSpBitrate90,
            160: lib.kSpBitrate160,
            320: lib.kSpBitrate320
        }

        lib.SpPlaybackSetBitrate(bitrates[self.args.bitrate])

        print_zeroconf_vars()

        if self.args.username and self.args.password:
            lib.SpConnectionLoginPassword(self.args.username,
                                          self.args.password)
Пример #8
0
    def __init__(self, error_cb=error_callback):
        pass_required = False
        if __name__ == "__main__":
            #Require username and password when used without a web server
            pass_required = True
        arg_parser = argparse.ArgumentParser(
            description='Web interface for Spotify Connect',
            parents=[audio_arg_parser])
        arg_parser.add_argument(
            '--debug',
            '-d',
            help='enable libspotify_embedded/flask debug output',
            action="store_true")
        arg_parser.add_argument('--key',
                                '-k',
                                help='path to spotify_appkey.key',
                                default='spotify_appkey.key',
                                type=file)
        arg_parser.add_argument('--username',
                                '-u',
                                help='your spotify username',
                                required=pass_required)
        arg_parser.add_argument('--password',
                                '-p',
                                help='your spotify password',
                                required=pass_required)
        arg_parser.add_argument(
            '--name',
            '-n',
            help='name that shows up in the spotify client',
            default='TestConnect')
        arg_parser.add_argument(
            '--bitrate',
            '-b',
            help='Sets bitrate of audio stream (may not actually work)',
            choices=[90, 160, 320],
            type=int,
            default=160)
        arg_parser.add_argument(
            '--credentials',
            '-c',
            help='File to load and save credentials from/to',
            default='credentials.json')
        self.args = arg_parser.parse_args()

        app_key = ffi.new('uint8_t *')
        self.args.key.readinto(ffi.buffer(app_key))
        app_key_size = len(self.args.key.read()) + 1

        self.credentials = dict({
            'device-id': str(uuid.uuid4()),
            'username': None,
            'blob': None
        })

        try:
            with open(self.args.credentials) as f:
                self.credentials.update({
                    k: v.encode('utf-8') if isinstance(v, unicode) else v
                    for (k, v) in json.loads(f.read()).iteritems()
                })
        except IOError:
            pass

        if self.args.username:
            self.credentials['username'] = self.args.username

        userdata = ffi.new_handle(self)

        self.config = {
            'version': 4,
            'buffer': C.malloc(0x100000),
            'buffer_size': 0x100000,
            'app_key': app_key,
            'app_key_size': app_key_size,
            'deviceId': ffi.new('char[]', self.credentials['device-id']),
            'remoteName': ffi.new('char[]', self.args.name),
            'brandName': ffi.new('char[]', 'DummyBrand'),
            'modelName': ffi.new('char[]', 'DummyModel'),
            'deviceType': lib.kSpDeviceTypeAudioDongle,
            'error_callback': error_cb,
            'userdata': userdata,
        }

        init = ffi.new('SpConfig *', self.config)
        print "SpInit: {}".format(lib.SpInit(init))

        lib.SpRegisterConnectionCallbacks(connection_callbacks, userdata)
        if self.args.debug:
            lib.SpRegisterDebugCallbacks(debug_callbacks, userdata)
        lib.SpRegisterPlaybackCallbacks(playback_callbacks, userdata)

        mixer_volume = int(mixer.getvolume()[0] * 655.35)
        lib.SpPlaybackUpdateVolume(mixer_volume)

        bitrates = {
            90: lib.kSpBitrate90k,
            160: lib.kSpBitrate160k,
            320: lib.kSpBitrate320k
        }

        lib.SpPlaybackSetBitrate(bitrates[self.args.bitrate])

        playback_setup()

        print_zeroconf_vars()

        if self.credentials['username'] and self.args.password:
            self.login(password=self.args.password)
        elif self.credentials['username'] and self.credentials['blob']:
            self.login(blob=self.credentials['blob'])
Пример #9
0
    def __init__(self, error_cb = error_callback, web_arg_parser = None):
        arg_parsers = [audio_arg_parser]
        if web_arg_parser:
            arg_parsers.append(web_arg_parser)
        arg_parser = argparse.ArgumentParser(description='Web interface for Spotify Connect', parents=arg_parsers)
        arg_parser.add_argument('--debug', '-d', help='enable libspotify_embedded/flask debug output', action="store_true")
        arg_parser.add_argument('--key', '-k', help='path to spotify_appkey.key (can be obtained from https://developer.spotify.com/my-account/keys )', default='spotify_appkey.key')
        arg_parser.add_argument('--username', '-u', help='your spotify username')
        arg_parser.add_argument('--password', '-p', help='your spotify password')
        arg_parser.add_argument('--name', '-n', help='name that shows up in the spotify client', default='TestConnect')
        arg_parser.add_argument('--bitrate', '-b', help='Sets bitrate of audio stream (may not actually work)', choices=[90, 160, 320], type=int, default=160)
        arg_parser.add_argument('--credentials', '-c', help='File to load and save credentials from/to', default='credentials.json')
        self.args = arg_parser.parse_args()

        print "Using libspotify_embedded version: {}".format(ffi.string(lib.SpGetLibraryVersion()))

        try:
            with open(self.args.key) as f:
                app_key = ffi.new('uint8_t *')
                f.readinto(ffi.buffer(app_key))
                app_key_size = len(f.read()) + 1
        except IOError as e:
            print "Error opening app key: {}.".format(e)
            print "If you don't have one, it can be obtained from https://developer.spotify.com/my-account/keys"
            sys.exit(1)


        self.credentials = dict({
            'device-id': str(uuid.uuid4()),
            'username': None,
            'blob': None
        })

        try:
            with open(self.args.credentials) as f:
                self.credentials.update(
                        { k: v.encode('utf-8') if isinstance(v, unicode) else v
                            for (k,v)
                            in json.loads(f.read()).iteritems() })
        except IOError:
            pass

        if self.args.username:
            self.credentials['username'] = self.args.username

        userdata = ffi.new_handle(self)

        if self.args.debug:
            lib.SpRegisterDebugCallbacks(debug_callbacks, userdata)

        self.config = {
             'version': 4,
             'buffer': C.malloc(0x100000),
             'buffer_size': 0x100000,
             'app_key': app_key,
             'app_key_size': app_key_size,
             'deviceId': ffi.new('char[]', self.credentials['device-id']),
             'remoteName': ffi.new('char[]', self.args.name),
             'brandName': ffi.new('char[]', 'DummyBrand'),
             'modelName': ffi.new('char[]', 'DummyModel'),
             'client_id': ffi.new('char[]', '0'),
             'deviceType': lib.kSpDeviceTypeAudioDongle,
             'error_callback': error_cb,
             'userdata': userdata,
        }

        init = ffi.new('SpConfig *' , self.config)
        init_status = lib.SpInit(init)
        print "SpInit: {}".format(init_status)
        if init_status != 0:
            print "SpInit failed, exiting"
            sys.exit(1)

        lib.SpRegisterConnectionCallbacks(connection_callbacks, userdata)
        lib.SpRegisterPlaybackCallbacks(playback_callbacks, userdata)

        mixer_volume = int(mixer.getvolume()[0] * 655.35)
        lib.SpPlaybackUpdateVolume(mixer_volume)

        bitrates = {
            90: lib.kSpBitrate90k,
            160: lib.kSpBitrate160k,
            320: lib.kSpBitrate320k
        }

        lib.SpPlaybackSetBitrate(bitrates[self.args.bitrate])

        playback_setup()

        print_zeroconf_vars()

        if self.credentials['username'] and self.args.password:
            self.login(password=self.args.password)
        elif self.credentials['username'] and self.credentials['blob']:
            self.login(blob=self.credentials['blob'])
        else:
            if __name__ == '__main__':
                raise ValueError("No username given, and none stored")