接口参考手册

这个参考手册描述了 feeluown 的几大组成部分,各组成部分的主要模块, 以及模块的相对稳定接口。

播放模块

播放模块由两部分组成:播放列表(Playlist)和播放器(Player)。

播放列表维护了一个媒体资源集合,并提供若干资源获取接口,播放器通过接口获取资源, 然后进行播放。这些接口包括: current_song, next_song, previous_song

播放列表吐资源给播放器的时候,是有一定的顺序的,我们称之为回放模式(PlaybackMode)。 回放模式有四种:单曲循环;顺序;循环;随机。上述三个资源访问接口吐资源的顺序都会受回放模式影响。

当播放列表 current_song 变化时,它会发出 song_changed 信号,播放器会监听该信号, 从而播放、停止(song 为空时)或者切换歌曲。播放歌曲时,播放器的状态(State)会发生变化, 当没有歌曲播放的时候,播放器为停止(stopped)状态,有歌曲播放的时候,为正在播放状态。 当一首歌开始播放后,播放器会发出 media_changed 信号, 当一首歌曲播放完毕时,播放器会发出 song_finished 信号。

播放列表和播放器之间的调用关系如下:

Playlist (Mpv)Player
 current_song.setter ---[song_changed]---> play_song
 ^ |
 | | <song==None>
 |<- play_song |--------------> stop
 |<- play_next/play_previous |
 |<- play_next <-| prepare_media
 |<- replay <-| <mode==one_loop> |
 | v
 | play ---[media_changed]--->
 [song_finished]
 |
 |
 ---- event(END_FILE)
 ^
 |
 MpvPlayer

通用管理模块

feeluown.task.is_in_loop_thread()[source]

check if current thread has event loop

classfeeluown.task.TaskKind(value)[source]
preemptive='preemptive'

preemptive task

cooperative='cooperative'

cooperative task

classfeeluown.task.PreemptiveTaskSpec(mgr, name)[source]

Preemptive task specification (threadsafe)

bind_coro(coro) Task[source]

run the coroutine and bind the task

it will cancel the previous task if exists

Returns:

asyncio.Task

bind_blocking_io(func, *args) Task[source]

run blocking io func in a thread executor, and bind the task

it will cancel the previous task if exists

Returns:

asyncio.Task

classfeeluown.task.TaskManager(*_)[source]

named task manager

Usage:

async deffetch_song():
 pass
task_name = 'unique-name'
task_spec = task_mgr.get_or_create(task_name, TaskType.preemptive)
task = task_spec.bind_coro(fetch_song())
get_or_create(name, kind=TaskKind.preemptive)[source]

get task spec, it will be created if not exists

Parameters:
  • name – task identifier(name)

  • kindTaskKind

TODO: client should register first, then get by name

GUI 相关管理模块

Note

目前,大部分 GUI 组件的接口都不稳定,我们在实现插件时,如果需要从操作 GUI 组件, 请调用以下模块的接口。如果我们想实现的功能通过以下接口在暂时实现不了, 请和 @cosven 联系。

GUI 组件

异常

HELP: I do not know how to design exception classes, as a result, these interfaces can be changed frequently.

exceptionfeeluown.excs.FuoException[source]
exceptionfeeluown.excs.LibraryException[source]
exceptionfeeluown.excs.ProviderIOError(message='', provider=None)[source]

Read/write data from/to provider failed

currently, all providers use requests to send http request, and many Requestexception are not catched, so ProviderIOError inherit RequestException.

exceptionfeeluown.excs.CreateReaderFailed(message='', provider=None)[source]

(DEPRECATED) use ProviderIOError instead

exceptionfeeluown.excs.ReaderException(message='', provider=None)[source]

(DEPRECATED) use ProviderIOError instead

exceptionfeeluown.excs.ReadFailed(message='', provider=None)[source]

(DEPRECATED) use ProviderIOError instead

exceptionfeeluown.excs.ResourceNotFound(*args, reason=Reason.not_found, **kwargs)[source]
classReason(value)[source]

Added in version v4.0.

exceptionfeeluown.excs.ProviderAlreadyRegistered[source]
exceptionfeeluown.excs.ModelNotFound(*args, reason=Reason.not_found, **kwargs)[source]

Model is not found

For example, a model identifier is invalid. Maybe ResourceNotFound is enough and this exception should be removed.

Added in version 3.7.7.

exceptionfeeluown.excs.MediaNotFound(*args, reason=Reason.not_found, **kwargs)[source]
classReason(value)[source]
exceptionfeeluown.excs.NoUserLoggedIn[source]

(DEPRECATED) return None when there is no user logged in