Idle. A freshly constructed FPlayer sits here. It holds a little memory and starts no extra threads. From idle, only setDataSource can move it to initialized.
initialized
Initialized. Compared with idle, the player now knows the input media source. Still no extra threads.
asyncPreparing
Asynchronously preparing. You get here by calling prepareAsync from initialized. This isn't a stable state: it waits for specific work to finish, then flips to prepared on its own. That work covers probing the media type, opening the file, opening decoders and starting decode threads, starting a read thread, opening the audio output device, and starting video output threads.
prepared
asyncPreparing lands here once its work is done. Some audio and video has already been buffered and decoded, so playback can begin at any moment.
started
Media (video or audio) is playing.
paused
Playback of media (video or audio) is paused.
completed
Playback of media (video or audio) finished. You can play it again from the start.
stopped
Every thread has released its resources. The audio device is closed.
end
Every buffer that needed manual release has been freed. A player in this state just waits for garbage collection to reclaim the rest.
idle, initialized, prepared, paused, completed, stopped, end, error. A stable state only changes when an API call moves it. It never shifts on its own.