Skip to main content

flet-media-scanner

A Flet extension for native Android MediaStore integration — save, list, and delete videos in the device Gallery without requiring broad storage permissions.

Built with 100% native Android Kotlin (MediaStore & MediaScannerConnection) and pure Dart Flet service bindings, with zero third-party Flutter plugin dependencies.


Features

  • 📱 Android MediaStore Scoped Storage: Save videos directly to Movies/<Album> without WRITE_EXTERNAL_STORAGE on Android 10+ (API 29+).
  • 🖼️ Instant Gallery Visibility: Media is immediately visible in Google Photos and device Gallery apps via native ContentResolver publishing and MediaScannerConnection.
  • 📋 List & Query: Query videos belonging to your app's custom album.
  • 🗑️ Content URI Deletion: Cleanly delete media using Android content:// URIs.
  • ⚡ Zero Third-Party Dependencies: No external Flutter packages needed.

Requirements

  • Platform: Android only (no-op / unsupported on desktop & iOS)
  • Android: API 21+ (minSdk 21; Scoped Storage optimized for API 29+)
  • Flet: >= 1.0.0
  • Python: >= 3.10

Installation

pip install flet-media-scanner

Or when developing locally in a workspace:

[tool.flet.extensions]
flet_media_scanner = "flet_media_scanner.Extension"

[tool.flet.dev_packages]
flet-media-scanner = "packages/flet-media-scanner"

Setup

Register the extension in your application's pyproject.toml:

[tool.flet.extensions]
flet_media_scanner = "flet_media_scanner.Extension"

Usage

import flet as ft
from flet_media_scanner import MediaScanner, SaveResult

async def main(page: ft.Page):
    # Initialize and register the service
    scanner = MediaScanner()
    page.services.append(scanner)
    page.update()

    # 1. Save a downloaded video to Gallery (Movies/MyVideos folder)
    result: SaveResult = await scanner.save_video(
        file_path="/data/user/0/com.example.app/cache/video.mp4",
        file_name="awesome_video.mp4",
        album="MyVideos",
    )

    if result.success:
        print(f"Saved successfully: {result.content_uri}")
        print(f"Gallery relative path: {result.relative_path}")
    else:
        print(f"Failed to save: {result.error}")

    # 2. List all videos in the custom album
    videos = await scanner.list_videos(album="MyVideos")
    for v in videos:
        print(f"Video: {v['display_name']} | URI: {v['content_uri']}")

    # 3. Delete a video by content URI
    if result.content_uri:
        deleted = await scanner.delete_video(result.content_uri)
        print("Deleted:", deleted)

    # 4. Trigger legacy media scanner for existing public files
    scanned = await scanner.scan_media("/storage/emulated/0/Movies/MyVideos/awesome_video.mp4")
    print("Scanned:", scanned)

ft.run(main)

API Reference

MediaScanner (Service)

Inherits from ft.Service. Must be added to page.services before invoking methods.

await save_video(file_path: str, file_name: str | None = None, album: str = "Vidsaver") -> SaveResult

Copies an app-private cache or temp video file into Android MediaStore.Video.Media (Movies/<album>).

  • file_path (str): Absolute filesystem path to the source video.
  • file_name (str | None): Target file name in the Gallery (defaults to the file basename).
  • album (str): Subdirectory name inside Movies/ (defaults to "Vidsaver").
  • Returns: SaveResult.

await list_videos(album: str = "Vidsaver") -> list[dict]

Queries all videos previously registered in the specified album.

  • album (str): Album subfolder inside Movies/.
  • Returns: List of dictionaries with keys:
    • display_name (str): File name shown in Gallery.
    • content_uri (str): Android content:// URI.
    • mime_type (str): Video MIME type (e.g. video/mp4).
    • relative_path (str): Directory path in storage (e.g. Movies/Vidsaver).
    • size (int): File size in bytes.
    • date_added (int): Unix timestamp added.
    • date_modified (int): Unix timestamp modified.

await delete_video(content_uri: str) -> bool

Deletes a media item from MediaStore using its content:// URI.

  • content_uri (str): Android MediaStore content URI.
  • Returns: True if deleted, False otherwise.

await scan_media(file_path: str) -> bool

Triggers Android native MediaScannerConnection.scanFile to index a file that already resides in public storage.

  • file_path (str): Absolute path to the file.
  • Returns: True if successfully indexed, False otherwise.

SaveResult (Dataclass)

Field Type Description
success bool True if the video was successfully saved and published.
content_uri str Android MediaStore content:// URI for the saved media.
display_name str Display name of the file in the Gallery.
mime_type str MIME type (e.g., video/mp4).
relative_path str Destination relative path (e.g., Movies/Vidsaver).
source_path str Original source path passed into save_video.
size int Size of the saved file in bytes.
error str Error description if success is False.

If your application needs more comprehensive media library functionality such as browsing albums, querying photos/videos/audio, thumbnails, permissions, media mutations, and live media change notifications, see flet-media-library.

flet-media-scanner is intentionally focused on Android MediaStore operations for saving, listing, deleting, and scanning videos.

Used in Vidsaver

flet-media-scanner is used in Vidsaver to handle Android media-library operations for downloaded videos.

Vidsaver uses the package to integrate downloaded media with Android's native MediaStore, allowing videos to be saved, scanned, listed, and managed without relying on a separate media-management layer.

This makes flet-media-scanner part of a real-world Flet application and demonstrates how the package can be used for native Android media integration in production-style projects.

Vidsaver: https://github.com/fazi-gondal/Vidsaver


License

MIT

Metadata

Release files for flet-media-scanner 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flet-media-scanner 1.0.3
File Size Uploaded Provenance
flet_media_scanner-1.0.3.tar.gz 12.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for flet-media-scanner 1.0.3
File Interpreter ABI Platform
flet_media_scanner-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 25.5 kB

Release files / flet_media_scanner-1.0.3.tar.gz

Download URL flet_media_scanner-1.0.3.tar.gz
Size 12.4 kB
Tags Source
SHA-256 checksum
How to use checksums
01cd5e06018ce5a96411e2f905a7e1b75eb7efa2e23f56e3d9610aff2a5da976
BLAKE2b-256 checksum
How to use checksums
680f61919aeaf4dac91e0a73df13ec70c93971299438c87b61f69d3042159f14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / flet_media_scanner-1.0.3-py3-none-any.whl

Download URL flet_media_scanner-1.0.3-py3-none-any.whl
Size 13.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b9ac3336a59c8743406a1e153467657011197f077f1ffea1e0d0aaf37bfd8e5f
BLAKE2b-256 checksum
How to use checksums
3c024caff7f0000a3403034cb9c0d9b061b379fdb7498f0903ae0a93d01668d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Security for flet-media-scanner 1.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page