Página de fotogramas ya funciona

parent 85efb35b
Showing with 91 additions and 23 deletions
......@@ -4,8 +4,10 @@ import 'package:ffmpeg_kit_flutter_new/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter_new/ffmpeg_session.dart';
import 'package:ffmpeg_kit_flutter_new/ffprobe_kit.dart';
import 'package:ffmpeg_kit_flutter_new/ffprobe_session.dart';
import 'package:ffmpeg_kit_flutter_new/log.dart';
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import '../modelo/modelo.dart';
......@@ -29,18 +31,23 @@ class PaginaFotograma extends StatefulWidget {
class _PaginaFotogramaState extends State<PaginaFotograma> {
int _fotogramaSeleccionado = 0;
int _ultimoFotograma = 0;
double _duracionVideo = 0;
final _buttons = _IconButtons.values;
Timer? timer;
@override
void initState() {
loadNumberFotogramas();
if(widget._archivo.fotograma != null){
_fotogramaSeleccionado = widget._archivo.fotograma!;
}
super.initState();
}
@override
void dispose() {
clearTemp();
super.dispose();
}
......@@ -100,7 +107,11 @@ class _PaginaFotogramaState extends State<PaginaFotograma> {
future: loadFotograma(_fotogramaSeleccionado),
builder: (context, asyncSnapshot) {
if(asyncSnapshot.connectionState == ConnectionState.done){
return Image.file(asyncSnapshot.data!);
imageCache.clear();
return Image.file(
asyncSnapshot.data!,
key: UniqueKey(),
);
}
else{
return Transform.scale(
......@@ -118,9 +129,14 @@ class _PaginaFotogramaState extends State<PaginaFotograma> {
max: _ultimoFotograma.toDouble(),
divisions: _ultimoFotograma,
value: _fotogramaSeleccionado.toDouble(),
label: _fotogramaSeleccionado.toString(),
label: (_fotogramaSeleccionado+1).toString(),
onChanged: (value) {
setState(() { _fotogramaSeleccionado = value.toInt(); });
setState(() {
_fotogramaSeleccionado = value.toInt();
});
widget._archivo.fotograma = _fotogramaSeleccionado;
widget._lista.actualizaSeleccionable(widget._indice, widget._archivo);
}
),
RichText(
......@@ -158,6 +174,9 @@ class _PaginaFotogramaState extends State<PaginaFotograma> {
if(_fotogramaSeleccionado < 0) _fotogramaSeleccionado = 0;
if(_fotogramaSeleccionado > _ultimoFotograma) _fotogramaSeleccionado = _ultimoFotograma;
});
widget._archivo.fotograma = _fotogramaSeleccionado;
widget._lista.actualizaSeleccionable(widget._indice, widget._archivo);
});
});
},
......@@ -179,6 +198,9 @@ class _PaginaFotogramaState extends State<PaginaFotograma> {
_fotogramaSeleccionado += button.variation;
if(_fotogramaSeleccionado < 0) _fotogramaSeleccionado = 0;
if(_fotogramaSeleccionado > _ultimoFotograma) _fotogramaSeleccionado = _ultimoFotograma;
widget._archivo.fotograma = _fotogramaSeleccionado;
widget._lista.actualizaSeleccionable(widget._indice, widget._archivo);
});
},
),
......@@ -195,43 +217,73 @@ class _PaginaFotogramaState extends State<PaginaFotograma> {
}
Future<void> loadNumberFotogramas() async {
FFprobeSession session = await FFprobeKit.executeAsync(
'ffprobe -v error -select_streams v:0 -count_packets \\ -show_entries stream=nb_read_packets -of csv=p=0 ${widget._archivo.file.absolute.path}'
// Obtener número de fotogramas
FFprobeSession session = await FFprobeKit.execute(
'-v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -of csv=p=0 -i ${widget._archivo.file.path}'
);
String? numFoto = await session.getOutput();
// Obtener duración del vídeo
FFprobeSession session2 = await FFprobeKit.execute(
'-v 0 -of csv="p=0" -select_streams V:0 -show_entries stream=duration -i ${widget._archivo.file.path}'
);
String? output = await session.getAllLogsAsString();
print(output);
String? durat = await session2.getOutput();
if(durat != null){
double? res = double.tryParse(durat);
if(res != null && res > 0){
setState(() {
_duracionVideo = res-1;
});
}
}
if(output != null){
int? res = int.tryParse(output);
if(numFoto != null){
int? res = int.tryParse(numFoto);
if(res != null && res > 0){
setState(() {
_ultimoFotograma = res;
_ultimoFotograma = res-1;
});
}
}
setState(() {
_ultimoFotograma = 1200;
});
}
Future<File> loadFotograma(int fotograma) async {
final directory = await getApplicationSupportDirectory();
// Este comando extrae un frame del timestamp dado. Por ahora solo extrae el primer frame
// TODO: CONVERTIR FOTOGRAMA A TIMESTAMP
String pathArchivo = widget._archivo.file.absolute.path;
String pathArchivo = widget._archivo.file.path;
String pathSalida = '${directory.absolute.path}${Platform.pathSeparator}fotograma.png';
// Cálculo de la timestamp del fotograma a extraer
final double timeStamp = (fotograma/_ultimoFotograma)*_duracionVideo;
String hour, min, sec;
sec = ((timeStamp % 60.0) % 60.0).toString();
while(sec.indexOf('.') < 2){
sec = '0$sec';
}
min = ((timeStamp / 60).floor() % 60).toString();
min = min.padLeft(2,'0');
hour = (timeStamp / 3600).floor().toString();
hour = hour.padLeft(2,'0');
// Este comando extrae un frame del timestamp dado
// La opción -y acepta hacer overwrite
// Si se quiere añadir timestamp se hace con -ss 00:00:00
String commando = '-y -i $pathArchivo -frames:v 1 $pathSalida';
FFmpegSession session = await FFmpegKit.executeAsync(commando);
String commando = '-y -i $pathArchivo -ss $hour:$min:$sec -frames:v 1 $pathSalida';
try{
FFmpegSession session = await FFmpegKit.execute(commando);
} on PlatformException {}
return File(pathSalida).create();
}
Future<void> removeFotograma() async {
Future<void> clearTemp() async {
final directory = await getApplicationSupportDirectory();
final fotograma = File('${directory.absolute.path}${Platform.pathSeparator}fotograma.png');
if(await fotograma.exists()){
await fotograma.delete();
final list = directory.listSync();
for(var arch in list){
await arch.delete();
}
}
}
......
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: "direct main"
description:
name: archive
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
url: "https://pub.dev"
source: hosted
version: "4.0.7"
async:
dependency: transitive
description:
......@@ -408,6 +416,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
posix:
dependency: transitive
description:
name: posix
sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62
url: "https://pub.dev"
source: hosted
version: "6.0.2"
provider:
dependency: "direct main"
description:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment