thumbails fix
This commit is contained in:
@@ -386,7 +386,7 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: _buildThumbnailPlaceholder(),
|
||||
// Overlay con icono de play
|
||||
// Overlay con gradiente
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
@@ -399,20 +399,6 @@ class _GestorVideosPageState extends State<GestorVideosPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.9),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.play_arrow_rounded,
|
||||
size: 16,
|
||||
color: AppTheme.of(context).primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'package:get_thumbnail_video/index.dart';
|
||||
import 'package:get_thumbnail_video/video_thumbnail.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:energy_media/theme/theme.dart';
|
||||
import 'package:energy_media/models/media/media_models.dart';
|
||||
@@ -132,6 +134,32 @@ class _EditVideoDialogState extends State<EditVideoDialog> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Genera un thumbnail automáticamente desde el video si no hay poster
|
||||
Future<void> _generateThumbnailFromVideo() async {
|
||||
if (widget.video.fileUrl == null || widget.video.fileUrl!.isEmpty) return;
|
||||
|
||||
try {
|
||||
// Generar thumbnail desde el video
|
||||
final thumbnailBytes = await VideoThumbnail.thumbnailData(
|
||||
video: widget.video.fileUrl!,
|
||||
imageFormat: ImageFormat.JPEG,
|
||||
maxWidth: 1280, // Alta calidad para poster
|
||||
quality: 85,
|
||||
);
|
||||
|
||||
if (thumbnailBytes != null && thumbnailBytes.isNotEmpty) {
|
||||
// Guardar el thumbnail generado como nueva portada (sin mostrar en UI)
|
||||
newPosterBytes = thumbnailBytes;
|
||||
newPosterFileName = 'thumbnail_${widget.video.fileName}.jpg';
|
||||
|
||||
debugPrint('✅ Thumbnail generado automáticamente para edición');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ Error generando thumbnail automático: $e');
|
||||
// No es crítico, el video se guardará sin poster
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _saveChanges() async {
|
||||
// Actualizar título
|
||||
if (titleController.text != widget.video.title) {
|
||||
@@ -175,6 +203,19 @@ class _EditVideoDialogState extends State<EditVideoDialog> {
|
||||
newPosterFileName!,
|
||||
);
|
||||
}
|
||||
// Si no hay poster existente y no se seleccionó/eliminó uno, generar automáticamente
|
||||
else if (widget.video.posterUrl == null ||
|
||||
widget.video.posterUrl!.isEmpty) {
|
||||
await _generateThumbnailFromVideo();
|
||||
// Si se generó thumbnail, subirlo
|
||||
if (newPosterBytes != null && newPosterFileName != null) {
|
||||
await widget.provider.updateVideoPoster(
|
||||
widget.video.mediaFileId,
|
||||
newPosterBytes!,
|
||||
newPosterFileName!,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mounted) return;
|
||||
Navigator.pop(context, true);
|
||||
|
||||
@@ -3,6 +3,8 @@ import 'dart:html' as html;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:get_thumbnail_video/index.dart';
|
||||
import 'package:get_thumbnail_video/video_thumbnail.dart';
|
||||
import 'package:energy_media/models/media/media_models.dart';
|
||||
import 'package:energy_media/providers/videos_provider.dart';
|
||||
import 'package:energy_media/theme/theme.dart';
|
||||
@@ -130,6 +132,37 @@ class _PremiumUploadDialogState extends State<PremiumUploadDialog> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Genera un thumbnail automáticamente desde el video si no se seleccionó poster
|
||||
Future<void> _generateThumbnailFromVideo() async {
|
||||
if (_videoBlobUrl == null || selectedVideo == null) return;
|
||||
|
||||
try {
|
||||
// Generar thumbnail desde el video
|
||||
final thumbnailBytes = await VideoThumbnail.thumbnailData(
|
||||
video: _videoBlobUrl!,
|
||||
imageFormat: ImageFormat.JPEG,
|
||||
maxWidth: 1280, // Alta calidad para poster
|
||||
quality: 85,
|
||||
);
|
||||
|
||||
if (thumbnailBytes != null && thumbnailBytes.isNotEmpty) {
|
||||
// Actualizar el provider con el thumbnail generado (sin mostrar en UI)
|
||||
widget.provider.webPosterBytes = thumbnailBytes;
|
||||
widget.provider.posterName =
|
||||
'thumbnail_${videoFileName ?? 'video'}.jpg';
|
||||
widget.provider.posterFileExtension = '.jpg';
|
||||
|
||||
// NO actualizar selectedPoster ni posterFileName para que no se muestre en UI
|
||||
// El thumbnail está disponible en el provider para subir automáticamente
|
||||
|
||||
debugPrint('✅ Thumbnail generado automáticamente (oculto en UI)');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ Error generando thumbnail automático: $e');
|
||||
// No es crítico, el video se subirá sin poster
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _uploadVideo() async {
|
||||
if (titleController.text.isEmpty ||
|
||||
selectedVideo == null ||
|
||||
@@ -148,6 +181,11 @@ class _PremiumUploadDialogState extends State<PremiumUploadDialog> {
|
||||
|
||||
setState(() => isUploading = true);
|
||||
|
||||
// Si no hay poster seleccionado, generar thumbnail automáticamente desde el video
|
||||
if (selectedPoster == null && _videoBlobUrl != null) {
|
||||
await _generateThumbnailFromVideo();
|
||||
}
|
||||
|
||||
// Procesar tags: separar por comas o espacios
|
||||
List<String>? tags;
|
||||
if (tagsController.text.isNotEmpty) {
|
||||
|
||||
Reference in New Issue
Block a user