-
Notifications
You must be signed in to change notification settings - Fork 0
docs: Add flutter download support documentation #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,163 @@ | ||||||
| --- | ||||||
| sidebar_position: 5 | ||||||
| --- | ||||||
|
|
||||||
| # Downloads | ||||||
|
|
||||||
| The Flutter TPStreams SDK provides comprehensive download functionality for offline video playback. This includes initiating downloads, managing ongoing tasks, and tracking progress through streams. | ||||||
|
|
||||||
| ## Enabling Download Support | ||||||
|
|
||||||
| You can enable download support directly in the player UI by setting the `showDownloadOption` parameter. When enabled, the player will display a download button. | ||||||
|
|
||||||
| ```dart | ||||||
| import 'package:tpstreams_player_sdk/tpstreams_player_sdk.dart'; | ||||||
|
|
||||||
| TPStreamPlayer( | ||||||
| assetId: 'YOUR_ASSET_ID', | ||||||
| accessToken: 'YOUR_ACCESS_TOKEN', | ||||||
| showDownloadOption: true, // Displays the download button in the player | ||||||
| offlineLicenseExpireDays: 15, // Optional: Duration in days for which the offline license is valid. Defaults to 15 days. | ||||||
| ) | ||||||
| ``` | ||||||
|
|
||||||
| ## Initiating a Download | ||||||
|
|
||||||
| Use the `startDownload` method from `TPStreamsDownloadManager` to initiate a video download for offline playback. | ||||||
|
|
||||||
| ### `startDownload` | ||||||
|
|
||||||
| ```dart | ||||||
| final downloadManager = TPStreamsDownloadManager(); | ||||||
|
|
||||||
| await downloadManager.startDownload( | ||||||
| assetId, // String: Required | ||||||
| accessToken, // String: Required | ||||||
| metadata, // Map<String, String> | null: Optional custom metadata | ||||||
| ); | ||||||
| ``` | ||||||
|
|
||||||
| | Parameter | Type | Description | | ||||||
| | :--- | :--- | :--- | | ||||||
| | `assetId` | `String` | Unique identifier for the video asset. | | ||||||
| | `accessToken` | `String` | Valid access token for the video. | | ||||||
| | `metadata` | `Map<String, String>` | (Optional) Any custom key-value pairs you want to attach to the download. | | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the
Suggested change
|
||||||
|
|
||||||
| ## Managing Downloads | ||||||
|
|
||||||
| ### Basic Operations | ||||||
|
|
||||||
| Use the `TPStreamsDownloadManager` to control active and completed downloads. | ||||||
|
|
||||||
| - **pauseDownload(DownloadAsset asset)**: Pauses an ongoing download. (**Note**: Currently supported on Android only. Throws `UnsupportedError` on iOS). | ||||||
| - **resumeDownload(DownloadAsset asset)**: Resumes a paused or failed download. (**Note**: Currently supported on Android only. Throws `UnsupportedError` on iOS). | ||||||
| - **cancelDownload(DownloadAsset asset)**: Cancels an ongoing download. | ||||||
| - **deleteDownload(DownloadAsset asset)**: Removes a downloaded video from local storage. | ||||||
| - **deleteAllDownloads()**: Removes all downloaded videos from the device. | ||||||
| - **getAllDownloads()**: Returns a `Future<List<DownloadAsset>>` containing all tracked downloads. | ||||||
|
|
||||||
| ## Download Events | ||||||
|
|
||||||
| The SDK uses a `Stream` to provide real-time updates on all download activities. This is the recommended way to keep your UI in sync with download states. | ||||||
|
|
||||||
| ### `downloadsStream` | ||||||
|
|
||||||
| Triggered periodically with the status of all current downloads. | ||||||
|
|
||||||
| ```dart | ||||||
| final downloadManager = TPStreamsDownloadManager(); | ||||||
|
|
||||||
| downloadManager.downloadsStream.listen((List<DownloadAsset> downloads) { | ||||||
| for (var asset in downloads) { | ||||||
| print("Video: ${asset.title}"); | ||||||
| print("Status: ${asset.state}"); | ||||||
| print("Progress: ${asset.progress}%"); | ||||||
| } | ||||||
| }); | ||||||
| ``` | ||||||
|
|
||||||
| ## Playing Downloaded Media | ||||||
|
|
||||||
| To play a video that has been downloaded, use the `TPStreamPlayer.offline` constructor. This ensures the player uses the local file instead of streaming from the network. | ||||||
|
|
||||||
| ```dart | ||||||
| TPStreamPlayer.offline( | ||||||
| assetId: 'YOUR_DOWNLOADED_ASSET_ID', | ||||||
| ) | ||||||
| ``` | ||||||
|
|
||||||
| ## Data Structures | ||||||
|
|
||||||
| ### `DownloadAsset` | ||||||
|
|
||||||
| The object returned in the `downloadsStream` and by `getAllDownloads()`. | ||||||
|
|
||||||
| | Property | Type | Description | | ||||||
| | :--- | :--- | :--- | | ||||||
| | `assetId` | `String` | Unique identifier for the video. | | ||||||
| | `title` | `String?` | Title of the video. | | ||||||
| | `state` | `DownloadState` | The current state of the download. | | ||||||
| | `progress` | `double` | Percentage of the download completed (0 to 100). | | ||||||
| | `metadata` | `Map<String, String>?` | Custom metadata attached to the download. | | ||||||
|
|
||||||
| ### `DownloadState` | ||||||
|
|
||||||
| An enum representing the lifecycle of a download: | ||||||
|
|
||||||
| - `notDownloaded`: The asset is not present locally. | ||||||
| - `downloading`: The asset is currently being downloaded. | ||||||
| - `paused`: The download has been paused (Android only). | ||||||
| - `completed`: The asset is fully downloaded and ready for offline play. | ||||||
| - `failed`: The download encountered an error. | ||||||
|
|
||||||
| ## Usage Example | ||||||
|
|
||||||
| ```dart | ||||||
| import 'package:flutter/material.dart'; | ||||||
| import 'package:tpstreams_player_sdk/tpstreams_player_sdk.dart'; | ||||||
|
|
||||||
| class MyDownloadPage extends StatefulWidget { | ||||||
| @override | ||||||
| _MyDownloadPageState createState() => _MyDownloadPageState(); | ||||||
| } | ||||||
|
|
||||||
| class _MyDownloadPageState extends State<MyDownloadPage> { | ||||||
| final _downloadManager = TPStreamsDownloadManager(); | ||||||
| List<DownloadAsset> _downloads = []; | ||||||
|
|
||||||
| @override | ||||||
| void initState() { | ||||||
| super.initState(); | ||||||
| // 1. Listen for updates | ||||||
| _downloadManager.downloadsStream.listen((downloads) { | ||||||
| setState(() { | ||||||
| _downloads = downloads; | ||||||
| }); | ||||||
| }); | ||||||
|
Comment on lines
+132
to
+136
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the Also, it's safer to check if the widget Here's a more robust implementation: class _MyDownloadPageState extends State<MyDownloadPage> {
final _downloadManager = TPStreamsDownloadManager();
List<DownloadAsset> _downloads = [];
StreamSubscription<List<DownloadAsset>>? _downloadsSubscription;
@override
void initState() {
super.initState();
_downloadsSubscription = _downloadManager.downloadsStream.listen((downloads) {
if (mounted) {
setState(() {
_downloads = downloads;
});
}
});
}
// ... build method ...
@override
void dispose() {
_downloadsSubscription?.cancel();
_downloadManager.dispose();
super.dispose();
}
} |
||||||
| } | ||||||
|
|
||||||
| @override | ||||||
| Widget build(BuildContext context) { | ||||||
| return ListView.builder( | ||||||
| itemCount: _downloads.length, | ||||||
| itemBuilder: (context, index) { | ||||||
| final asset = _downloads[index]; | ||||||
| return ListTile( | ||||||
| title: Text(asset.title ?? 'Untitled'), | ||||||
| subtitle: Text("${asset.state.name} - ${asset.progress.toStringAsFixed(1)}%"), | ||||||
| trailing: IconButton( | ||||||
| icon: Icon(Icons.delete), | ||||||
| onPressed: () => _downloadManager.deleteDownload(asset), | ||||||
| ), | ||||||
| ); | ||||||
| }, | ||||||
| ); | ||||||
| } | ||||||
|
|
||||||
| @override | ||||||
| void dispose() { | ||||||
| _downloadManager.dispose(); | ||||||
| super.dispose(); | ||||||
| } | ||||||
| } | ||||||
| ``` | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code example for
startDownloadis a bit ambiguous. It's not clear if the parameters are positional or named, and the example mixes a method call with parameter type comments, which can be confusing.For better clarity, I suggest adopting the documentation style used in
player-methods.md: first show the method signature, and then provide a clean example of how to call it.For example:
startDownloadFuture<void> startDownload(String assetId, String accessToken, {Map<String, String>? metadata})Initiates a video download for offline playback.
Example:
(Note: The signature above is just an example; please use the actual method signature.)