# Mybili and the case for keeping your own copy of a favourites folder

> Mybili is a Laravel and Vue application that polls a bilibili favourites folder every five minutes, caches the metadata, and downloads the videos to a local path you control for playback and for a media server such as Emby. The cost is a cookie-based login that has to be refreshed by hand unless you run the browser extension.

**ellermister/mybili** — 哔哩哔哩收藏夹备份程序 ~ アレ 视频不见了哟！

- Repository: https://github.com/ellermister/mybili
- Website: https://mybili.eller.top/
- Stars: 709 · Forks: 41
- Language: PHP
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/ellermister-mybili

## The five minute poll is the whole design

Mybili is a bilibili favourites download tool, positioned as a program you cannot do without on your NAS. The mechanism is straightforward enough to describe in a sentence and important enough to be worth a paragraph.

Every five minutes the application fetches all the videos in your favourites folder and caches the important information about them, the title, the description and the cover. That cached list is then handed to a queue, and the videos you have favourited are downloaded locally at the highest available quality.

The five minute interval is a design decision with consequences. It is fast enough that a newly favourited video appears in your local library within minutes, and slow enough that the platform is not hammered with requests. It also means the application is always slightly behind the source of truth, and the cached metadata is the authority for what the tool believes your library contains rather than a live query.

The queue is what makes downloads asynchronous rather than a blocking operation in the request cycle, and the project pairs it with Redis for that purpose. The project documentation notes that the current version has deprecated Redis for storing persistent data, and that it is now used only for temporary caching and for the async task queue, which is a meaningful change from earlier versions.

The primary language is PHP with a Laravel application, the licence is MIT, and the last push to the repository was on 2026-08-16.

## Deployment is a compose file with Redis and SQLite, nothing else

The deployment instructions are written for a NAS, and the shape of the compose file is the clearest description of the application.

First you create the storage directory that will hold the downloaded media:

```bash
mkdir /mnt/user/mybili/data -p
```

Then you create a docker-compose.yml at /mnt/user/mybili with two services:

```yaml
services: 
    mybili:
        image: ellermister/mybili
        ports:
            - "5151:80"
        volumes:
            - "./data:/app/storage/app/public"
            - db-data:/data

        environment:
            REDIS_HOST: redis
            REDIS_DB: 3
            DB_CONNECTION: sqlite
            DB_DATABASE: /data/database.sqlite
    redis:
        image: redis
        volumes:
            - redis-data:/data
        command: redis-server --save 60 1 --loglevel warning

volumes:
  db-data:
  redis-data:
```

The design decisions are visible in there. The media directory is bind mounted rather than managed as a named volume, and the project explains why, that it makes the files easier to use from outside the container, which matters when the point is to feed a media library. The database is SQLite by default, stored on a named volume, holding the text type information about favourites, videos and danmaku. Redis runs with a save interval of 60 seconds and a single saved copy, and warning level logging, and it is on database 3.

Start and stop are the two commands you would expect:

```bash
docker-compose up -d
```

and

```bash
docker-compose down
```

The web interface is then on port 5151, and the container's own port 80 or 443 can both be used.

## The cookie problem, and why the browser extension exists

Everything in this application depends on being logged in as you, and the project is unusually honest about how that login decays.

There are two routes to get the cookie. The manual one involves installing a browser extension called Get cookies.txt LOCALLY, logging into bilibili in your browser, exporting the cookie file in Netscape format, and then visiting the cookie upload path at your instance address. Once the file is uploaded the sync starts automatically.

The automatic route exists because of a specific problem with the manual one. The documentation explains that after you upload the cookie session it expires after a few days, so long-term automatic sync is not achieved. The reason is that when you use the logged-in web version of bilibili at the same time, it obtains a new short-lived token, and mybili does not update, and has no mechanism to fetch a new one itself. And if mybili did fetch a new token, that would sign out your web session, which the author says is bad from both an implementation complexity and a user experience point of view.

So the answer is a separate Chrome extension, built by taking the approach used by the plugin above and processing it further, which only needs your mybili address filled in and then syncs the cookie to mybili automatically and without any user action. You download the project as a zip, extract it, enable developer mode in the browser extensions page, load the unpacked extension from the directory, and then enter your mybili address including the port, for example http://192.168.1.200:5151.

That is a real operational commitment, and it is the price of the automatic path.

## Four settings decide what actually gets downloaded

The settings page, reached at the settings path on your instance, holds the switches that matter. The documentation lists four main items and notes that sync is off by default.

Favourites sync is the master switch, and it syncs the favourites information every five minutes. Multi-part download controls whether all the segments of a video are downloaded or only the first, which matters for any title split into parts. Danmaku download stores the bullet comments in the database, and video download is the toggle that allows video file downloads to be triggered at all.

The danmaku feature is the one that goes beyond simple archiving. The tool supports caching video parts and the full danmaku locally, and can play them back online with a danmaku preview loaded, which the Vue frontend does with the artplayer plugin for danmaku.

The frontend dependencies show the shape of the interface. Vue 3 with vue-router, artplayer as the player, virtua for virtualised lists, and vue-virtual-sortable for the drag and drop ordering in the collection view, plus vue-i18n for localisation. The dev stack is Vite with the laravel-vite-plugin bridging to Laravel, Tailwind CSS, and TypeScript configuration split across tsconfig.json, tsconfig.app.json and tsconfig.node.json.

So the web page shows the favourites list with information about each entry, allows online preview playback, and lets you manage the collection.

## Media library output and the file layout that makes it work

The feature that makes this useful beyond a personal video folder is the generation of a multimedia readable directory file, adapted for media libraries such as Emby.

That sounds small and is not. A media server needs a directory structure and metadata to recognise a file as a piece of a larger work rather than as an unrelated video, and a flat folder of downloaded files will be indexed badly or not indexed at all. Generating the directory file locally is what lets you point Emby at the path and have a library appear.

The application also has subscription support, where you add a collection or an uploader to subscribe to and new videos are discovered and downloaded automatically. That is the part of the design that turns it from a one-off backup into a standing pipeline, and it is the same pipeline the five minute sync feeds.

Inside the container the logs come from several different services, and the documentation shows the listing:

```bash
/app # ls /var/log
queue.log.0        schedule.log.0     supervisord.log.0  web.log.0
```

Four files, from the queue, the scheduler, the process supervisor and the web server. When the web interface is unreachable or throwing errors, the guidance points at the Laravel log:

```bash
tail -f /app/storage/logs/laravel.log
```

That split is a useful signal about the architecture. There is a scheduler process, a queue worker process and a web process, and the container is running them under a supervisor, which is the standard way to run a Laravel application that has background work to do.

## Three things that changed and will break an old configuration

The update notes at the end of the documentation are the part to read before you upgrade, because each item changes behaviour rather than just adding features. Updates are done by pulling the latest image, checking GitHub or Docker Hub for a new version.

The first is that the current version has deprecated Redis for storing persistent data, and it is now only used for writing temporary cache and async queue state. Any configuration that assumed your session or data lived in Redis needs revisiting.

The second is that the .env file is no longer used for configuration, and environment variables are used to override instead. The guidance is to remove the .env entry from your docker-compose.yml if you have one.

The third is that the cookie.txt file mapping has been deprecated in favour of storing the cookie in the database, and again you should remove the cookie.txt entry from your compose file.

Each of these is a small thing individually and together they are the usual cost of a project that has moved from a simpler configuration to a more explicit one. The .env.example file in the repository still shows the full Laravel default set, with DB_CONNECTION set to sqlite, SESSION_DRIVER and CACHE_STORE and QUEUE_CONNECTION all pointing at redis, REDIS_DB at 3, and the AWS variables for a bucket that is not configured by default. That file is a reference for what the environment variables can be, not a template to copy wholesale.

The repository layout shows the rest. There is a Dockerfile, a download-video.sh script, a deploy/ directory, the Laravel application directories, a resources/ directory for the frontend, and a tailwind.config.js alongside the vite config. The Docker build pulls in ffmpeg and yt-dlp, choosing the right static build for the target architecture, and installs yt-dlp for the download side.

## Conclusion

Mybili suits someone with a large bilibili favourites folder who wants a local copy that keeps working when the platform does, and who already runs a NAS or a home server, since the design assumes a mounted storage path and a media server in the loop. It does not suit someone who wants a one-off download, and it does not suit a deployment where the cookie refresh is going to be a problem, because the manual export expires within days. Before you deploy it, read the notes on removed features, because Redis now holds only temporary cache and queue state, the .env file is gone in favour of environment variables, and the cookie.txt volume mapping has been replaced by storage in the database, so an old configuration will not behave the way it used to.

## FAQ

### What does Mybili do?

It is a bilibili favourites download tool for a NAS. Every five minutes it fetches all the videos in your favourites folder and caches the title, description and cover, then a queue downloads the favourited videos locally at the highest quality, with a web interface for browsing and previewing them.

### How do I deploy Mybili with Docker Compose?

Create the storage directory with mkdir /mnt/user/mybili/data -p, write a docker-compose.yml with the mybili and redis services and a bind mount for the media directory, then run docker-compose up -d. The web interface is published on port 5151 and the database defaults to SQLite with Redis used for cache and the queue.

### Why does my Mybili cookie expire after a few days?

Because using the logged-in web version of bilibili at the same time makes it obtain a new short-lived token, and Mybili neither updates nor fetches one itself, since doing so would sign out your browser session. The project provides a separate Chrome extension that syncs the cookie to Mybili automatically once you fill in your instance address.

### Which settings control downloading in Mybili?

The settings page has four main switches: favourites sync as the master switch, multi-part download for videos split into segments, danmaku download to store bullet comments in the database, and video download to allow file downloads to be triggered. Sync is off by default.

### Can Mybili feed an Emby library?

Yes. It supports generating a multimedia readable directory file adapted for media libraries such as Emby, and it also supports subscriptions to collections and uploaders so that new videos are discovered and downloaded automatically.

## Sources

- [ellermister/mybili on GitHub](https://github.com/ellermister/mybili)
- [License: MIT](https://github.com/ellermister/mybili/blob/main/LICENSE)
- [Project website](https://mybili.eller.top/)
- [README](https://github.com/ellermister/mybili/blob/main/README.md)
- [Releases](https://github.com/ellermister/mybili/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ellermister-mybili
