87 lines
2.9 KiB
Dart
87 lines
2.9 KiB
Dart
import 'dart:async';
|
|
import 'dart:ui' as ui;
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:stream_chat_flutter/src/utils/device_segmentation.dart';
|
|
import 'package:thumblr/thumblr.dart' as thumblr;
|
|
import 'package:video_thumbnail/video_thumbnail.dart';
|
|
|
|
///
|
|
// ignore: prefer-match-file-name
|
|
class _IVideoService {
|
|
_IVideoService._();
|
|
|
|
/// Singleton instance of [_IVideoService]
|
|
static final _IVideoService instance = _IVideoService._();
|
|
|
|
/// Generates a thumbnail image data in memory as UInt8List.
|
|
///
|
|
/// The video source can be a local video file or a URL.
|
|
///
|
|
/// Thumbnails are not supported on Web at this time.
|
|
///
|
|
/// If no [video] path is supplied, or if a thumbnail cannot be generated,
|
|
/// returns [generatePlaceholderThumbnail]. A stock placeholder image.
|
|
///
|
|
/// For desktop, you can specify the position of the video to generate
|
|
/// the thumbnail.
|
|
///
|
|
/// For mobile, you can specify the maximum height or width for the thumbnail
|
|
/// or 0 for same resolution as the original video. The lower quality value
|
|
/// creates lower quality of the thumbnail image, but it gets ignored for
|
|
/// PNG format.
|
|
Future<Uint8List?> generateVideoThumbnail({
|
|
String? video,
|
|
ImageFormat imageFormat = ImageFormat.PNG,
|
|
int maxHeight = 0,
|
|
int maxWidth = 0,
|
|
int timeMs = 0,
|
|
int quality = 10,
|
|
}) async {
|
|
if (kIsWeb || video == null) {
|
|
final placeholder = await generatePlaceholderThumbnail();
|
|
return placeholder;
|
|
}
|
|
if (isDesktopDevice) {
|
|
try {
|
|
final thumbnail = await thumblr.generateThumbnail(filePath: video);
|
|
final byteData = await thumbnail.image.toByteData(
|
|
format: ui.ImageByteFormat.png,
|
|
);
|
|
final bytesList = byteData?.buffer.asUint8List() ?? Uint8List(0);
|
|
if (bytesList.isNotEmpty) {
|
|
return bytesList;
|
|
} else {
|
|
return await generatePlaceholderThumbnail();
|
|
}
|
|
} catch (e) {
|
|
// If the thumbnail generation fails, return a placeholder image.
|
|
final placeholder = await generatePlaceholderThumbnail();
|
|
return placeholder;
|
|
}
|
|
} else if (isMobileDevice) {
|
|
return VideoThumbnail.thumbnailData(
|
|
video: video,
|
|
imageFormat: imageFormat,
|
|
maxHeight: maxHeight,
|
|
maxWidth: maxWidth,
|
|
timeMs: timeMs,
|
|
quality: quality,
|
|
);
|
|
}
|
|
throw Exception('Could not generate thumbnail');
|
|
}
|
|
|
|
/// Generates a placeholder thumbnail by loading placeholder.png from assets.
|
|
Future<Uint8List> generatePlaceholderThumbnail() async {
|
|
final placeholder = await rootBundle
|
|
.load('packages/stream_chat_flutter/images/placeholder.png');
|
|
return placeholder.buffer.asUint8List();
|
|
}
|
|
}
|
|
|
|
/// Get instance of [_IVideoService]
|
|
// ignore: non_constant_identifier_names
|
|
_IVideoService get StreamVideoService => _IVideoService.instance;
|