fanplayer: a portable ffmpeg based video player that talks to the graphics device directly
A portable video player based on ffmpeg for windows and android platform.
At a glance
- What is it?
- fanplayer is a small video player written in C that decodes with ffmpeg and renders straight to the platform's own APIs, GDI and Direct3D on Windows and AudioTrack and ANativeWindow on Android, with no SDL in between. It suits someone who wants a dependency-light player for local files and network streams, and it is a demonstration codebase rather than a packaged application.
- Who is it for?
- fanplayer fits a developer who wants to read a complete, readable implementation of ffmpeg based video rendering, or a user who wants a small portable player for local files, RTSP and RTMP streams that runs without a runtime installer, and it does not fit someone who wants a maintained general purpose media player with a library of formats, subtitle support and a polished interface.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 140 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
No SDL, and a rendering path straight to the platform
fanplayer is described in the README as a portable video player based on ffmpeg for Windows and Android. The distinguishing architectural decision is stated immediately: it is a simple and light weight player implementation without SDL or other third party library, and the player core codes are written in C language, KISS and easy to read.
Rendering is done by talking to the operating system directly. On the win32 platform, video rendering uses gdi and direct3d APIs and audio rendering uses the waveout API. On Android, audio rendering goes through AudioTrack and video rendering through the ANativeWindow API.
That is the whole design in one sentence, and it explains both the size of the thing and its scope. A player built on SDL inherits SDL's abstraction, its build requirements and its version constraints, along with SDL's own idea of how a window and a surface work. Dropping it removes all of that and replaces it with two platform backends you have to write and maintain yourself, in exchange for a binary with no external graphics dependency and a rendering path you can read end to end.
The repository layout matches that split. There is a src directory for the shared core, a player-windows directory and a player-android directory for the two platform ports, an avkcpdemuxer directory and an ffrdpdemuxer directory for the two custom protocols, a docs directory, a logo directory, a todo.txt, and the readme.md itself.
The primary language is recorded as C, and the licence is LGPL-3.0.
The feature list, which reads like a changelog of the work
Twenty-one numbered features are listed, and they are more informative as a history of the codebase than as a specification.
The performance claims come first: low memory and cpu usage, and audio and video synchronized very well. The README makes the comparison explicit, describing smooth playback of many video files with low cpu and memory usage compared with ffplay of official ffmpeg, along with high performance, compatibility and stability.
Then the Windows specifics: gdi and direct3d rendering on win32, dxva2 hardware acceleration on windows, rotation for direct3d video rendering, and support for overlay for the win32 platform. The direct3d rotation is listed separately from the general rotation support, which tells you the two rendering backends do not have identical capabilities, and the hotkey list confirms it by marking rotate video as working only for d3d rendering mode.
Then the input and output paths: support for dshow, gdigrab and vfwcap through avdevice of ffmpeg, which are the three Windows capture devices, and mediacodec hardware decoding on android. Also take a video snapshot with support to save into jpeg and png, and the mouse right button drag to select area zoom.
Playback control has its own group: variable speed playback from 1 percent to 100 percent and beyond at 200 percent, step seek forward and backward, a very fast async seek operation taking 0ms delay, and support for waveform and spectrum visual effect.
The last group is the networking and broadcast work: support for stream selection, network media stream playback, auto-reconnect for live stream playing, support for avkcp and ffrdp protocol, support for livedesk ffrdp remote control, and support for yolo-fastest detection.
testplayer and its hotkeys, which is the usable documentation
The README does not describe a user interface, and the closest thing to documentation of how the player behaves is a companion program called testplayer, described as a simple test player for fanplayer, with a list of hotkeys.
The list is the practical reference for anyone trying the player.
ctrl+O - open file
ctrl+E - switch visual effect
ctrl+M - switch between letter box and stretch rect
ctrl+R - switch between gdi and d3d
ctrl+A - switch audio stream
ctrl+V - switch video stream
ctrl+S - take a snapshot of video
ctrl+F - step seek forward
ctrl+B - step seek backward
ctrl+up - play speed up
ctrl+down - play speed down
ctrl+T - switch speed type
ctrl+X - rotate video (only for d3d rendering mode)
ctrl+C - record current playing media to record.mp4 file
ctrl+W - set window size to video size
ctrl+D - display video definition
ctrl+0 - restore zoom
ctrl+L - enter livedesk ffrdp remote control mode
ctrl+Y - enable/disable yolo-fastest detection Several of those bindings are worth pausing on, because they describe the design rather than the interface. ctrl+R switching between gdi and d3d at runtime means the two rendering backends are alternatives rather than a fallback, and a user can compare them on the same content. ctrl+A and ctrl+V switching audio and video streams separately is what makes the stream selection feature usable for files that carry more than one of either. ctrl+C recording the current playing media to a record.mp4 file is the one that is a genuine departure from a plain player, and it works for whatever is playing, including a network stream.
The last two entries are also a reminder of where this project sits. ctrl+L enters livedesk ffrdp remote control mode, and ctrl+Y toggles yolo-fastest detection, which is a computer vision model. Neither is a media player feature, and both point at a broadcast and monitoring origin for the codebase.
Two custom protocols, and why they are separate directories
The avkcpdemuxer and ffrdpdemuxer directories are the parts of the project that are not about playing video at all, and they are the reason the feature list has entries like support for avkcp and ffrdp protocol and support for livedesk ffrdp remote control.
A demuxer in the ffmpeg sense is the component that takes a container or a stream format and hands the framework a sequence of packets. The two directories therefore contain protocol implementations that let the player open something that is not a plain file.
The ffrdp one is tied to a named product, livedesk, and the hotkey binding for it says remote control mode rather than just playback. That distinction matters when reading the feature list. The list mixes three quite different kinds of capability: a local desktop player with hardware acceleration and a zoom gesture, a network player that can pull RTSP and RTMP streams, as the repository topics record, and a broadcast tool that can be driven remotely and can run object detection over the picture.
The last of those is the odd one out, and it is the clearest sign of what this codebase actually is. A yolo-fastest detection toggle in a video player is not something a general purpose player would ship. It belongs to a pipeline where the video is being watched by a machine as well as by a person, and the same codebase is being reused for that.
That also frames the project's real audience. The reader is likely a developer working on broadcast or monitoring tooling who found a compact ffmpeg rendering implementation and extended it, rather than a user looking for a media player to download.
What the README does not tell you
The documentation is thin in a specific way, and it is worth naming the gaps rather than working around them.
There is no build section. The README does not say how to compile the Windows player or the Android player, what toolchain is needed, what version of the ffmpeg libraries is expected, or how ffmpeg itself is obtained and linked. The top level has a Dockerfile-like absence of build instructions, and the docs directory is not described.
There is also no install path for an end user. The project describes itself as portable, and the core is a single directory of C with no third party graphics library, but the README gives no download, no release binary, and the repository has no GitHub releases. So a user without a compiler and an ffmpeg development environment has nothing to install.
The wiki is the answer the README points to. It says want to learn more about fanplayer, please visit our wiki, and gives the URL under the rockcarry organisation. That is where the build instructions and the deeper documentation are expected to be, and it is also where a reader should look before assuming the repository is the whole story.
The date at the end of the README is worth noting for the same reason. The file ends with the author name rockcarry and the date 2016.1.7. The repository has been updated since, with the last push on 2026-06-05, but the README itself is old, which explains why the features are listed as a flat numbered list with no narrative, and why the project is described in the present tense of several years ago.
Against ffplay, and against a packaged player
The comparison the project itself draws is with ffplay of official ffmpeg, and it is worth taking seriously rather than as marketing.
ffplay is a small example program that ships with ffmpeg and plays using the library's own window handling, which historically meant SDL. The trade-off between the two is a straight one. ffplay needs an ffmpeg build and its windowing dependency, and it is a demonstration rather than a product, with the interface people expect from an example program. fanplayer removes the windowing dependency and gives you two native rendering backends and a set of broadcast oriented features, and in exchange you inherit a codebase you have to compile yourself and keep in step with the ffmpeg API.
Against a packaged player, the difference is what the project is for. A packaged player ships with a format library, subtitle handling, playlist management, a settings UI and a maintainer who deals with codec changes. fanplayer has none of that, and instead gives you a small readable core that renders whatever ffmpeg can decode, with hardware acceleration on both platforms, and that you can extend.
The trade is extension against completeness. If the requirement is a player that works out of the box for ordinary video files, this is the wrong shape of project and a packaged player is the right answer. If the requirement is a video pipeline you are going to modify, where you need to capture from a dshow device, drive a remote camera, run detection over the frames, and record what you saw, then a codebase this small and this readable is a reasonable foundation, and one that is far easier to follow than a large SDL based player.
The LGPL-3.0 licence matters for that second case, since a library under those terms can be used in a larger application with obligations around how modifications are distributed, and the practical advice for anyone embedding this code is to read the licence text rather than assume it behaves like MIT or BSD.
Editorial conclusion
fanplayer fits a developer who wants to read a complete, readable implementation of ffmpeg based video rendering, or a user who wants a small portable player for local files, RTSP and RTMP streams that runs without a runtime installer, and it does not fit someone who wants a maintained general purpose media player with a library of formats, subtitle support and a polished interface. Before using it, read the wiki linked from the README, since the repository itself is a README, a source tree and a todo file with no build documentation, and note that the Windows and Android players are separate directories built for their own platforms, so the source you are reading is not what a Windows user would compile without the toolchain the project expects.
Frequently asked questions
What rendering APIs does fanplayer use on Windows and Android?
On the win32 platform it uses gdi and direct3d APIs for video rendering and the waveout API for audio. On Android it uses AudioTrack for audio and the ANativeWindow API for video, and it is described as a player without SDL or another third party library.
Does fanplayer support hardware decoding?
The feature list names mediacodec hardware decoding on Android and dxva2 hardware acceleration on Windows, alongside rotation support for direct3d video rendering and an overlay option for the win32 platform.
How do I build or obtain fanplayer?
The README does not document a build or install step, and the repository has no GitHub releases, so there is nothing to download. It directs readers to the project wiki for more information, and the source is in the src directory with separate player-windows and player-android directories for the two platform ports.
What are the avkcpdemuxer and ffrdpdemuxer directories in fanplayer?
They are separate directories for the avkcp and ffrdp protocol implementations, and the feature list names support for both protocols along with livedesk ffrdp remote control and auto-reconnect for live stream playback. The project topics also record rtmp and rtsp.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/rockcarry-fanplayer)Was this useful?