Historial del chat

ChatGPT

Sora

Photo Realistic Image GPT

Explorar GPT

Proyectos

Nuevo proyecto

Hoy

Bat de Data Videos y donde PyInstaller

Ayer

morph cut búsqueda y Shotcut

30 días anteriores

Cambio color HTML Flash

Recibir correos en Gmail

Convert Local Time UTC

Transferir archivos USB S10e

Mejoras para HeyGen

Remuestreo vs cambio inteligente

Descargar jq Windows

febrero

Espectrometría y cromatografía forense

Serpiente y rana venenosa

Renovación y posibles problemas

Error en archivo ZIP

Problema con PayPal Checkout

enero

Preguntar sobre webs

Ver planesAcceso ilimitado, características de Team y más

Abrir barra lateral

ChatGPT o3-mini-high

ChatGPT o3-mini-high

Compartir

PLUS

Dijiste:

Hola chat intento hacer un exe de phyton, donde se ubica pyinstaller?

ChatGPT dijo:

Razonado sobre ubicación de PyInstaller durante 6 segundos

Cuando instalas PyInstaller con pip, se ubica en la carpeta Scripts de tu instalación de Python. Por ejemplo, en Windows si tu Python está en C:\Python39, encontrarás el ejecutable en C:\Python39\Scripts\pyinstaller.exe.

Si trabajas en un entorno virtual, estará en la carpeta Scripts de ese entorno. Asegúrate de que la ruta esté en tu PATH para poder ejecutarlo directamente desde la línea de comandos con el comando pyinstaller.

o3-mini-high

Dijiste:

Me dice esto:
C:\Windows\System32>C:\Program Files\Python313\Scripts\pyinstaller --onefile "C:\Windows\System32\Automation-scripts\face_morpher\automated_morph_all.py" --add-data "C:\Windows\System32\Automation-scripts\face_morpher\shape_predictor_68_face_landmarks.dat";.
"C:\Program" no se reconoce como un comando interno o externo,
programa o archivo por lotes ejecutable.

C:\Windows\System32>

ChatGPT dijo:

Razonado durante 4 segundos

El error se debe a que Windows interpreta el espacio en "Program Files" como separador de comandos. Para solucionarlo, debes encerrar la ruta completa del ejecutable entre comillas. Por ejemplo:

csharp

Copiar

"C:\Program Files\Python313\Scripts\pyinstaller" --onefile "C:\Windows\System32\Automation-scripts\face_morpher\automated_morph_all.py" --add-data "C:\Windows\System32\Automation-scripts\face_morpher\shape_predictor_68_face_landmarks.dat";.

De esta forma, el sistema reconoce correctamente la ruta y ejecuta el comando.

o3-mini-high

Dijiste:

C:\Windows\System32>"C:\Program Files\Python313\Scripts\pyinstaller.exe" --onefile "C:\Windows\System32\Automation-scripts\face_morpher\automated_morph_all.py" --add-data "C:\Windows\System32\Automation-scripts\face_morpher\shape_predictor_68_face_landmarks.dat";.
Error: Do not run pyinstaller from C:\Windows\System32. cd to where your code is and run pyinstaller from there. Hint: You can open a terminal where your code is by going to the parent folder in Windows file explorer and typing cmd into the address bar.

C:\Windows\System32>

ChatGPT dijo:

Razonado sobre el error de PyInstaller durante 9 segundos

El error se debe a que PyInstaller detecta que estás ejecutándolo desde la carpeta del sistema C:\Windows\System32, lo cual no es recomendable. Para solucionarlo, sigue estos pasos:

Abre una terminal en la carpeta de tu proyecto:

Navega a la carpeta donde se encuentra tu código. Por ejemplo, abre el Explorador de Windows, ve a

C:\Windows\System32\Automation-scripts\face_morpher, haz clic en la barra de direcciones, escribe cmd y presiona Enter. Esto abrirá una ventana de comandos en el directorio correcto.

Ejecuta PyInstaller desde allí:

Una vez en la terminal dentro del directorio de tu proyecto, ejecuta el comando sin incluir rutas que te obliguen a iniciar desde System32. Por ejemplo:

csharp

Copiar

"C:\Program Files\Python313\Scripts\pyinstaller.exe" --onefile automated_morph_all.py --add-data "shape_predictor_68_face_landmarks.dat;."

Asegúrate de ajustar la sintaxis de --add-data según corresponda para Windows (el separador es ;).

Siguiendo estos pasos deberías poder crear tu archivo ejecutable sin problemas.

o3-mini-high

Dijiste:

Y no hya forma de meter pyinstaller.exe en path o similar y que siempre se ejecute?

ChatGPT dijo:

Razonado durante 10 segundos

Sí, es posible. Para hacerlo, debes agregar la carpeta que contiene el archivo pyinstaller.exe a la variable de entorno PATH de Windows. De esta forma podrás ejecutarlo desde cualquier ubicación sin tener que escribir la ruta completa. Aquí te dejo los pasos:

Abrir Configuración de Variables de Entorno:

Haz clic derecho en "Este equipo" o "Mi PC" y selecciona "Propiedades".

Luego, ve a "Configuración avanzada del sistema".

En la ventana que se abre, haz clic en "Variables de entorno".

Editar la variable PATH:

En "Variables del sistema", busca la variable Path y selecciónala, luego haz clic en "Editar".

Agrega una nueva entrada con la ruta a la carpeta de Scripts de Python, por ejemplo:

makefile

Copiar

C:\Program Files\Python313\Scripts

Acepta todos los cambios y cierra las ventanas.

Reiniciar la terminal:

Abre una nueva ventana del símbolo del sistema para que se apliquen los cambios.

Con esto podrás ejecutar pyinstaller desde cualquier ubicación. Recuerda, además, cambiar de directorio a la carpeta de tu proyecto antes de ejecutar PyInstaller, ya que se recomienda no hacerlo desde carpetas del sistema como C:\Windows\System32.

o3-mini-high

Dijiste:

como era en VB6 la instruccion para hacer que string separados contenido por comas, lo haga un array?

ChatGPT dijo:

Razonado sobre cadenas en VB6 durante 18 segundos

En VB6 puedes utilizar la función Split para dividir una cadena en un array, separando por el delimitador que especifiques. Por ejemplo:

vb

Copiar

Dim arr() As String
arr = Split("dato1,dato2,dato3", ",")

Con esto, arr(0) contendrá "dato1", arr(1) tendrá "dato2" y así sucesivamente. Si tu cadena proviene de una variable, simplemente reemplaza el literal por el nombre de la variable.

o3-mini-high

Dijiste:

Me podrias dar todas las constantes para commondialog en VB6, estilo:
OFN_FILEMUSTEXIST

ChatGPT dijo:

Razonado durante 53 segundos

A continuación te presento una lista completa de las constantes (flags) que se usan con el CommonDialog en VB6 (y en la API de Windows para los cuadros de diálogo de archivos). Estas constantes se utilizan, por ejemplo, en la estructura OPENFILENAME para definir el comportamiento del diálogo:

OFN_READONLY (&H00000001): Abre el archivo en modo solo lectura.

OFN_OVERWRITEPROMPT (&H00000002): Muestra una advertencia si se intenta sobrescribir un archivo existente.

OFN_HIDEREADONLY (&H00000004): Oculta la opción de solo lectura en el cuadro de diálogo.

OFN_NOCHANGEDIR (&H00000008): Evita que el diálogo cambie el directorio actual de la aplicación.

OFN_SHOWHELP (&H00000010): Muestra el botón de ayuda en el cuadro de diálogo.

OFN_ENABLEHOOK (&H00000020): Permite usar una función hook para personalizar el comportamiento del diálogo.

OFN_ENABLETEMPLATE (&H00000040): Permite utilizar una plantilla personalizada para el diálogo.

OFN_ENABLETEMPLATEHANDLE (&H00000080): Similar a la anterior, pero utiliza un handle para la plantilla.

OFN_NOVALIDATE (&H00000100): Omite la validación del nombre del archivo.

OFN_ALLOWMULTISELECT (&H00000200): Permite seleccionar múltiples archivos a la vez.

OFN_EXTENSIONDIFFERENT (&H00000400): Indica que la extensión del archivo ha cambiado.

OFN_PATHMUSTEXIST (&H00000800): Requiere que el directorio especificado exista.

OFN_FILEMUSTEXIST (&H00001000): Requiere que el archivo seleccionado exista.

OFN_CREATEPROMPT (&H00002000): Solicita confirmación para crear el archivo si no existe.

OFN_SHAREAWARE (&H00004000): Evita que el archivo se comparta mientras está abierto.

OFN_NOREADONLYRETURN (&H00008000): No permite que el usuario abra el archivo en modo solo lectura.

OFN_NOTESTFILECREATE (&H00010000): No prueba la creación del archivo.

OFN_NONETWORKBUTTON (&H00020000): Oculta el botón de red en el diálogo.

OFN_NOLONGNAMES (&H00040000): Deshabilita el uso de nombres largos (obsoleto en sistemas modernos).

OFN_EXPLORER (&H00080000): Utiliza el estilo del Explorador de Windows en el diálogo.

OFN_NODEREFERENCELINKS (&H00100000): No sigue accesos directos (links).

OFN_LONGNAMES (&H00200000): Permite el uso de nombres largos.

OFN_ENABLEINCLUDENOTIFY (&H00400000): Activa notificaciones al incluir archivos.

OFN_ENABLESIZING (&H00800000): Permite que el cuadro de diálogo sea redimensionable.

OFN_DONTADDTORECENT (&H02000000): Evita que el archivo se agregue a la lista de recientes.

OFN_FORCESHOWHIDDEN (&H10000000): Fuerza la visualización de archivos ocultos, incluso si están marcados como tal.

Con estos flags puedes configurar de forma muy detallada el comportamiento de los cuadros de diálogo (por ejemplo, en un diálogo de abrir o guardar archivo) a través del control CommonDialog en VB6.

Nota: Estos valores están definidos en el encabezado commdlg.h de la API de Windows y son compatibles con VB6 a través del CommonDialog Control.

o3-mini-high

Dijiste:

Me las podrias dar en formato vb56, como
Global OFN_READONLY = &H00000001

ChatGPT dijo:

Razonado durante 10 segundos

Aquí tienes las constantes en formato VB6 (VB5/VB6) para el CommonDialog, declaradas de forma global:

vb

Copiar

Global OFN_READONLY = &H00000001
Global OFN_OVERWRITEPROMPT = &H00000002
Global OFN_HIDEREADONLY = &H00000004
Global OFN_NOCHANGEDIR = &H00000008
Global OFN_SHOWHELP = &H00000010
Global OFN_ENABLEHOOK = &H00000020
Global OFN_ENABLETEMPLATE = &H00000040
Global OFN_ENABLETEMPLATEHANDLE = &H00000080
Global OFN_NOVALIDATE = &H00000100
Global OFN_ALLOWMULTISELECT = &H00000200
Global OFN_EXTENSIONDIFFERENT = &H00000400
Global OFN_PATHMUSTEXIST = &H00000800
Global OFN_FILEMUSTEXIST = &H00001000
Global OFN_CREATEPROMPT = &H00002000
Global OFN_SHAREAWARE = &H00004000
Global OFN_NOREADONLYRETURN = &H00008000
Global OFN_NOTESTFILECREATE = &H00010000
Global OFN_NONETWORKBUTTON = &H00020000
Global OFN_NOLONGNAMES = &H00040000
Global OFN_EXPLORER = &H00080000
Global OFN_NODEREFERENCELINKS = &H00100000
Global OFN_LONGNAMES = &H00200000
Global OFN_ENABLEINCLUDENOTIFY = &H00400000
Global OFN_ENABLESIZING = &H00800000
Global OFN_DONTADDTORECENT = &H02000000
Global OFN_FORCESHOWHIDDEN = &H10000000

Puedes copiar este bloque en un módulo global para tener disponibles estas constantes en toda tu aplicación VB6.

o3-mini-high

Dijiste:

Gracias Chat... Y como podria en VB6 si tengo el path de un archivo de video mp4, como puedo saber la tasa de FPS, los pixeles de ancho y alto y la duracion y el codec?

ChatGPT dijo:

Razonado durante 1m 2s

No existe en VB6 una función nativa que extraiga directamente metadatos (FPS, resolución, duración, codec) de un archivo de video MP4. Sin embargo, puedes lograrlo utilizando alguno de estos dos métodos:

1. Usando DirectShow y la interfaz IMediaDet

DirectShow (parte de DirectX) ofrece la interfaz IMediaDet, que te permite obtener información como la duración, tasa de frames (FPS), ancho y alto del video. Sin embargo, hay algunos puntos a considerar:

Requisitos:

Necesitas tener instaladas y registradas las librerías necesarias, en particular qedit.dll. En sistemas modernos esta DLL puede no venir por defecto, por lo que deberás obtenerla y registrarla manualmente.

Complejidad para el codec:

Aunque IMediaDet facilita la obtención de la duración, FPS y dimensiones, obtener información sobre el codec implica explorar el grafo de filtros de DirectShow, lo cual es más complejo.

Ejemplo básico:

Este es un ejemplo simplificado (sin manejo de codec) que muestra cómo obtener duración, FPS, ancho y alto. Deberás declarar y referenciar la interfaz IMediaDet (lo cual puede implicar declarar las interfaces COM manualmente o incluir una librería de DirectShow):

vb

Copiar

' Declaración (simplificada) de la variable de objeto de IMediaDet
Dim MediaDet As IMediaDet
Set MediaDet = New MediaDet

' Especifica la ruta completa del archivo de video
MediaDet.Filename = "C:\ruta\video.mp4"
MediaDet.CurrentStream = 0 ' Asumimos que el stream de video es el 0

Dim dDuration As Double, dFPS As Double
Dim lWidth As Long, lHeight As Long

dDuration = MediaDet.StreamLength ' Duración en segundos
dFPS = MediaDet.FrameRate ' Tasa de frames (FPS)
lWidth = MediaDet.VideoWidth ' Ancho en píxeles
lHeight = MediaDet.VideoHeight ' Alto en píxeles

MsgBox "Duración: " & dDuration & " seg." & vbCrLf & _
"FPS: " & dFPS & vbCrLf & _
"Ancho: " & lWidth & " px" & vbCrLf & _
"Alto: " & lHeight & " px"

Nota: Configurar IMediaDet en VB6 puede ser complicado debido a la gestión de COM y a la necesidad de tener correctamente registradas las librerías de DirectShow.

2. Utilizando el componente COM de MediaInfo

Una alternativa más sencilla es utilizar MediaInfo, una herramienta gratuita que ofrece un componente COM para extraer metadatos de archivos multimedia. Con MediaInfo puedes obtener fácilmente FPS, resolución, duración y codec.

Pasos a seguir:

Descarga e instala MediaInfo desde su sitio oficial.

Registra la DLL (si es necesario) y agrega la referencia al componente MediaInfo en tu proyecto VB6.

Ejemplo de código con MediaInfo:

vb

Copiar

' Asegúrate de haber agregado la referencia al componente MediaInfo en tu proyecto VB6
Dim MI As New MediaInfo
Dim videoPath As String
videoPath = "C:\ruta\video.mp4"

MI.Open videoPath

Dim fps As String, width As String, height As String, duration As String, codec As String
fps = MI.Get("Video", 0, "FrameRate")
width = MI.Get("Video", 0, "Width")
height = MI.Get("Video", 0, "Height")
duration = MI.Get("Video", 0, "Duration") ' En milisegundos
codec = MI.Get("Video", 0, "CodecID")

MI.Close

MsgBox "FPS: " & fps & vbCrLf & _
"Ancho: " & width & " px" & vbCrLf & _
"Alto: " & height & " px" & vbCrLf & _
"Duración: " & duration & " ms" & vbCrLf & _
"Codec: " & codec

En este ejemplo, se extrae la información del primer stream de video (índice 0). La duración se obtiene en milisegundos; si lo prefieres, puedes convertirla a segundos dividiéndola entre 1000.

Conclusión

Aunque VB6 no ofrece una función interna para obtener estos metadatos, tienes dos rutas principales:

DirectShow/IMediaDet: Más integrada en el ecosistema de Windows, pero con mayor complejidad y dependiente de ciertas DLL (como qedit.dll).

MediaInfo: Más sencilla de implementar mediante su componente COM y con una API muy amigable para extraer toda la información deseada (incluyendo el codec).

Elige la opción que mejor se adapte a tus necesidades y entorno de desarrollo.

o3-mini-high

Dijiste:

Prefiero ffmpeg

ChatGPT dijo:

Razonado durante 32 segundos

Si prefieres usar ffmpeg, lo más habitual es aprovechar ffprobe (que viene incluido en la distribución de ffmpeg) para extraer metadatos del video, como la resolución, FPS, duración y codec.

La idea es que desde VB6 ejecutes ffprobe mediante una llamada a la línea de comandos y captures su salida, para luego parsearla y extraer la información. Existen dos métodos comunes:

Método 1: Redirigir la salida a un archivo temporal

Ejecutar ffprobe con redirección de salida:

Por ejemplo, puedes usar un comando similar a este:

batch

Copiar

ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 "C:\ruta\video.mp4" > C:\temp\ffprobe_output.txt

Leer el archivo desde VB6:

Después de ejecutar el comando con la función Shell, abres el archivo ffprobe_output.txt, lees su contenido y extraes cada línea (cada dato se imprime en una línea).

Método 2: Usar el objeto WScript.Shell para capturar la salida

Esta opción es más directa porque permite capturar la salida estándar del comando sin necesidad de archivos intermedios. Para ello debes agregar (o crear) una instancia del objeto WScript.Shell.

A continuación, un ejemplo de código en VB6:

vb

Copiar

Dim wsh As Object
Dim oExec As Object
Dim sOutput As String
Dim arr() As String

' Crea la instancia del objeto WScript.Shell
Set wsh = CreateObject("WScript.Shell")

' Ejecuta ffprobe y captura la salida.
' Asegúrate de que ffprobe esté en el PATH o usa la ruta completa (por ejemplo: "C:\ffmpeg\bin\ffprobe.exe")
Set oExec = wsh.Exec("cmd /c ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 ""C:\ruta\video.mp4""")
sOutput = oExec.StdOut.ReadAll

' Separa la salida en líneas (cada línea corresponde a un dato)
arr = Split(sOutput, vbCrLf)

' Asegúrate de que se hayan obtenido al menos 5 líneas
If UBound(arr) >= 4 Then
Dim videoWidth As String, videoHeight As String, codecName As String, frameRate As String, duration As String

videoWidth = arr(0) ' Ancho
videoHeight = arr(1) ' Alto
codecName = arr(2) ' Codec
frameRate = arr(3) ' FPS (la tasa de frames, aunque a veces se presenta como fracción, por ejemplo "30000/1001")
duration = arr(4) ' Duración en segundos (o en formato decimal)

MsgBox "Ancho: " & videoWidth & " px" & vbCrLf & _
"Alto: " & videoHeight & " px" & vbCrLf & _
"Codec: " & codecName & vbCrLf & _
"FPS: " & frameRate & vbCrLf & _
"Duración: " & duration & " seg."
Else
MsgBox "No se pudo obtener la información del video."
End If

Notas adicionales

Rutas y PATH:

Asegúrate de que la ruta al archivo de video sea correcta.

Si ffprobe no está en el PATH, deberás usar la ruta completa (por ejemplo, "C:\ffmpeg\bin\ffprobe.exe").

Salida de ffprobe:

El comando usado genera la información en líneas separadas, en este orden:

Ancho (width)

Alto (height)

Nombre del codec (codec_name)

Tasa de frames (avg_frame_rate)

Duración (duration)

Si deseas más control o un formato distinto (como JSON), ffprobe permite cambiar el formato de salida mediante la opción -of json, pero en VB6 parsear JSON puede ser más complicado.

FPS en forma de fracción:

Ten en cuenta que el valor de FPS puede venir expresado como fracción (por ejemplo, "30000/1001"). Si necesitas el valor numérico, tendrás que convertir esa fracción a un número decimal.

Con esta aproximación utilizando ffprobe podrás extraer la información del video que necesitas desde VB6.

o3-mini-high

Dijiste:

Y mira, pesandolo bien, donde encuentro "MediaInfo"?

ChatGPT dijo:

**Razonado sobre ubicación de MediaInfo** durante un par de segundos

Puedes obtener MediaInfo desde su sitio oficial. Sólo visita:

https://mediaarea.net/en/MediaInfo

Allí encontrarás las descargas para diversas plataformas, incluyendo la versión para Windows, la cual puede incluir el componente COM que podrías usar en VB6. Una vez descargado, sigue las instrucciones de instalación para integrarlo en tu proyecto.

o3-mini-high

Dijiste:

He instalado mediainfo, y hay varias dll, pero no se como cual es el com
LIBCURL.DLL
MediaInfo.dll
MediaInfo_InfoTip.dll
MediaInfo_PackageHelper.dll
MediaInfo_WindowsShellExtension.dll
WebView2Loader.dll

ChatGPT dijo:

Razonado durante 20 segundos

El componente COM que puedes utilizar en VB6 es el que viene contenido en MediaInfo.dll. Para que VB6 lo reconozca como componente COM, debes registrarlo en el sistema usando regsvr32. Por ejemplo, desde una línea de comandos con privilegios de administrador, ejecuta:

batch

Copiar

regsvr32 "C:\ruta\a\MediaInfo.dll"

Una vez registrado, podrás agregarlo como referencia en tu proyecto VB6 y usar sus métodos para extraer los metadatos de tus archivos multimedia.

o3-mini-high

Dijiste:

No deja registrarse y no deja que se incluya como referencia...

ChatGPT dijo:

Razonado durante 22 segundos

El problema es que la versión de MediaInfo que instalaste no expone un componente COM listo para usar en VB6. En otras palabras, la DLL llamada MediaInfo.dll es la librería nativa para obtener información de archivos multimedia, pero no está diseñada como un objeto COM que puedas registrar y referenciar directamente en tu proyecto VB6.

Tienes dos alternativas:

Usar la versión de línea de comandos (mediainfo.exe):

Puedes ejecutar mediainfo.exe desde VB6 (por ejemplo, mediante el objeto WScript.Shell) y capturar la salida para parsearla y extraer la información que necesites (como FPS, resolución, duración y codec).

Un ejemplo sencillo en VB6 sería:

vb

Copiar

Dim wsh As Object
Dim execObj As Object
Dim output As String

' Crear la instancia de WScript.Shell
Set wsh = CreateObject("WScript.Shell")

' Ejecutar mediainfo.exe y capturar la salida.
' Asegúrate de que mediainfo.exe esté en el PATH o usa la ruta completa.
Set execObj = wsh.Exec("cmd /c mediainfo.exe ""C:\ruta\video.mp4""")
output = execObj.StdOut.ReadAll

MsgBox output

De esta forma, la salida de mediainfo.exe contendrá los metadatos del video que luego puedes procesar según lo necesites.

Utilizar o desarrollar un wrapper COM:

Existen algunos proyectos o ejemplos en Internet donde se ha creado un wrapper COM para la librería MediaInfo. Esto implicaría desarrollar (o encontrar) una capa intermedia que invoque las funciones de MediaInfo y exponga una interfaz COM que pueda ser referenciada en VB6. Esta opción es más compleja y puede requerir conocimientos adicionales en otros lenguajes o en el desarrollo de componentes COM.

En resumen, si lo que buscas es una integración sencilla en VB6, te recomiendo utilizar la versión de línea de comandos (mediainfo.exe) y capturar su salida. Esto evita tener que lidiar con el registro y la referenciación de componentes COM que, en este caso, no están incluidos en la versión que instalaste.

o3-mini-high

Dijiste:

Casi mejor me regreso al codigo que me has dado de ffprobe:

ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 "C:\ruta\video.mp4" > C:\temp\ffprobe_output.txt

Como lo podria meter en un archivo bat y ejecutarlo desde vb6 con CreateProcess con pipes, que ya lo tengo hecho, solo que me acepte el bat que cree con la "C:\ruta\video.mp4"

ChatGPT dijo:

Razonado durante 21 segundos

Puedes crear un archivo BAT que acepte el path del video como parámetro y luego ejecutarlo con CreateProcess (o con tu método de pipes). Por ejemplo, crea un archivo llamado ejecutar_ffprobe.bat con el siguiente contenido:

bat

Copiar

@echo off
REM Usa %~1 para quitar comillas extra del primer argumento y lo envuelve en comillas.
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 "%~1" > C:\temp\ffprobe_output.txt

Con este BAT, cuando lo ejecutes pasando como argumento la ruta del video (por ejemplo, "C:\ruta\video.mp4"), ffprobe procesará ese archivo y redirigirá la salida a C:\temp\ffprobe_output.txt.

Importante:

Asegúrate de que la ruta a ffprobe esté en el PATH o de usar la ruta completa dentro del BAT (por ejemplo, "C:\ffmpeg\bin\ffprobe.exe").

Recuerda que CreateProcess no ejecuta directamente archivos BAT, por lo que deberás invocar cmd.exe con el parámetro /c. Por ejemplo, desde VB6 tu comando podría ser:

vb

Copiar

cmd.exe /c "C:\ruta\ejecutar_ffprobe.bat" "C:\ruta\video.mp4"

De esta forma, el BAT recibirá "C:\ruta\video.mp4" como el primer argumento y lo usará en el comando de ffprobe. Con esto integras tu proceso de extracción de metadatos de forma dinámica desde VB6 utilizando CreateProcess con pipes.

o3-mini-high

Dijiste:

Estoy haciendo esto:
Open Arch1Short$ For Output As 1
Print #1, "@echo off"
Print #1, "Rem Usa %~1 para quitar comillas extra del primer argumento y lo envuelve en comillas."
Print #1, "ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1" + "%~1"

Esta bien? Es que no entiendo mucho que quieres decir con:
Rem Usa %~1

ChatGPT dijo:

**Reasoned about ffprobe in batch files** durante 19 segundos

La idea es que el BAT reciba la ruta del video como argumento, y el modificador %~1 hace lo siguiente:

%1: Representa el primer argumento pasado al archivo BAT.

%~1: Elimina las comillas que pudiera tener ese argumento. Esto es útil para evitar dobles comillas innecesarias cuando luego tú envuelves el valor en comillas.

Por ejemplo, en el BAT querrías que la línea final sea algo así:

bat

Copiar

ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 "%~1" > C:\temp\ffprobe_output.txt

Si estás creando el BAT desde VB6, tu código podría ajustarse de esta forma para incluir correctamente las comillas y espacios:

vb

Copiar

Open Arch1Short$ For Output As #1
Print #1, "@echo off"
Print #1, "Rem Usa %~1 para quitar comillas extra del primer argumento y lo envuelve en comillas."
Print #1, "ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 ""%~1"" > C:\temp\ffprobe_output.txt"
Close #1

Notas importantes:

La doble comilla "" en VB6 se interpreta como una comilla literal en la cadena, de modo que ""%~1"" se convertirá en "%~1" en el archivo BAT.

Asegúrate de que la ruta a ffprobe.exe esté en el PATH o reemplázala por la ruta completa dentro del BAT.

Si el BAT no se ejecuta correctamente, verifica que la redirección (> C:\temp\ffprobe_output.txt) tenga acceso de escritura en esa ubicación.

En resumen, %~1 es un modificador que elimina las comillas del primer argumento, y tú lo usas para asegurarte de que, al envolverlo nuevamente en comillas, se gestione correctamente la ruta, sobre todo si ésta contiene espacios.

o3-mini-high

Dijiste:

Mira Chat, tengo un Path que es asi:
LngPath$ = "P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CMD INSERTADO EN VB6\"

Le paso por:
sShortPath = Space$(255)
lRet = GetshortPathName(LngPath$, sShortPath, 255)

Y me devuelve:
sShortPath = "P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CMD INSERTADO EN VB6\"

GetshortPathName solo funciona con archivos, no con directorios?

ChatGPT dijo:

**Razonado sobre GetshortPathName y directorios** durante 7 segundos

La función GetShortPathName funciona tanto para archivos como para directorios. Sin embargo, en algunos casos puede devolver el mismo path que le pasas. Esto suele ocurrir porque:

La generación de nombres 8.3 puede estar deshabilitada: En algunas unidades o configuraciones de Windows se deshabilita la creación de nombres cortos (8.3) para mejorar el rendimiento o por cuestiones de configuración. Si no existe un nombre corto diferente, la función devuelve el nombre largo.

El directorio ya podría estar en formato corto: Aunque es poco común, es posible que el nombre ya esté en formato 8.3.

Para comprobarlo, podrías verificar la configuración de la unidad con el comando fsutil 8dot3name query P: en una ventana de comandos con privilegios de administrador. Esto te indicará si la generación de nombres cortos está habilitada en esa unidad.

o3-mini-high

Dijiste:

Me dice:
C:\>fsutil 8dot3name query P:
El estado del volumen es 1 (la creación de nombres 8dot3 está DESHABILITADA)
El estado del Registro es 2 (configuración por volumen: valor predeterminado)

Según la configuración anterior, la creación de nombres 8dot3 está DESHABILITADA en "P:"

Como se habilita?

ChatGPT dijo:

**Razonado sobre habilitar nombres 8.3** durante 9 segundos

Para habilitar la creación de nombres 8.3 en el volumen P:, debes ejecutar un comando en una ventana de símbolo del sistema con privilegios de administrador. Por ejemplo:

batch

Copiar

fsutil 8dot3name set P: 0

Este comando configura el volumen P: para que genere nombres cortos (8.3). El parámetro 0 indica que se debe habilitar la generación de nombres 8.3 en ese volumen.

Pasos adicionales y consideraciones:

Verificar el cambio:

Después de ejecutar el comando, puedes verificar la configuración con:

batch

Copiar

fsutil 8dot3name query P:

Deberías ver que el "estado del volumen" cambia a 0, lo que indica que la creación de nombres 8.3 está habilitada.

Archivos existentes:

Ten en cuenta que este cambio afecta la creación de nombres cortos para nuevos archivos. Los archivos ya existentes en el volumen no obtendrán automáticamente un nombre corto; normalmente se asigna el nombre corto cuando se crea el archivo.

Reinicio o re-montaje:

En algunos casos, puede ser necesario reiniciar el sistema o desmontar y volver a montar el volumen para que la nueva configuración surta efecto en su totalidad.

Esta configuración puede ser útil, por ejemplo, si dependes de funciones como GetShortPathName en VB6 para obtener el path corto de un archivo o directorio.

o3-mini-high

Dijiste:

Si, a pesar de haberla habilitado, me sigue dando como respuesta:

LngPath$ = "P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CMD INSERTADO EN VB6\"

Le paso por:
sShortPath = Space$(255)
lRet = GetshortPathName(LngPath$, sShortPath, 255)

Y me devuelve:
sShortPath = "P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CMD INSERTADO EN VB6\"

Si reinicio funcionara, o habria que hacer algo para que actualice todos los archivos y directorios?

ChatGPT dijo:

Razonado durante 6 segundos

El comportamiento que observas es normal. Cuando la creación de nombres 8.3 está deshabilitada y luego se habilita, Windows no genera de forma retroactiva los nombres cortos para los archivos y directorios que ya existen. Es decir:

Archivos y directorios creados mientras estaba deshabilitado:

No tendrán un nombre corto asignado, por lo que GetShortPathName devolverá la misma ruta larga.

Archivos y directorios creados después de habilitarla:

Se les asignará un nombre corto automáticamente (siempre que la configuración del volumen lo permita).

Un reinicio del sistema no forzará la generación retroactiva de nombres cortos para los elementos ya existentes. Para que un directorio obtenga un nombre corto, tendrías que recrearlo (por ejemplo, copiar su contenido a un nuevo directorio creado después de habilitar 8dot3).

En resumen, si necesitas el nombre corto de un directorio ya existente, tendrás que moverlo o renombrarlo de alguna forma para que se genere el nombre corto según la nueva configuración.

o3-mini-high

Dijiste:

Ok, y no hay ninguna forma de que actualice todo automaticamente? como cuando se el da a indexar un disco, que empeiza a indexar todos los directorios y archivos

ChatGPT dijo:

Razonado durante 7 segundos

No existe una forma nativa en Windows de forzar la regeneración automática de nombres cortos para archivos y directorios ya existentes. Cuando la creación de nombres 8.3 está deshabilitada, Windows simplemente no genera estos nombres para los elementos creados en ese período, y habilitar la función después no "actualiza" retroactivamente los elementos ya existentes.

Algunas alternativas serían:

Renombrar o mover archivos/directorios: Al renombrarlos o copiarlos a una ubicación nueva (después de haber habilitado 8.3), se generará el nombre corto. Esto puede automatizarse con un script, pero implica modificar los nombres o ubicaciones de los elementos.

Script de procesamiento masivo: Podrías desarrollar un script que recorra todos los archivos y directorios y los renombre (por ejemplo, añadiendo y quitando un carácter temporalmente), forzando así la generación del nombre corto. Sin embargo, esto es complejo y puede causar efectos secundarios, especialmente en aplicaciones que dependen de rutas fijas.

En resumen, Windows no proporciona un comando o proceso equivalente a la indexación de disco que actualice retroactivamente todos los nombres cortos. Tendrías que recurrir a procesos manuales o scripts para forzar esa regeneración.

o3-mini-high

Dijiste:

Ok, pues vaya, un problema a futuro, me imagino que por defecto el disco de arranque normalmente C:\ siempre tiene habilitada la creacion de nombres cortos?

ChatGPT dijo:

Razonado durante 8 segundos

En la mayoría de las instalaciones estándar de Windows, la unidad de arranque (normalmente C:) tiene habilitada la creación de nombres cortos (8.3) por defecto. Esto se hace para mantener compatibilidad con aplicaciones antiguas que dependen de esos nombres. Sin embargo, es posible que en algunos sistemas o por configuraciones de rendimiento, los administradores hayan decidido deshabilitarla en otras unidades o incluso en la de sistema, pero lo más habitual es que C:\ la tenga activa. Puedes verificarlo ejecutando:

batch

Copiar

fsutil 8dot3name query C:

Este comando te mostrará el estado actual en esa unidad.

o3-mini-high

Dijiste:

He cambiado de directorio los archivos, los he copiado a un directorio nuevo, pero sigue dandome el path completo con espacios, y lo malo es que para archivos bat los espacios son complicados

ChatGPT dijo:

Razonado durante 30 segundos

Cuando GetShortPathName te devuelve el mismo path largo, significa que no existe un nombre corto generado para ese directorio. Aunque hayas habilitado la creación de nombres 8.3 para el volumen, Windows no asigna retroactivamente nombres cortos a archivos o directorios que ya fueron creados (o copiados) sin ellos.

Algunas consideraciones:

Creación de nuevos directorios:

Si creas un directorio nuevo después de habilitar la función, lo normal es que se genere un nombre corto. Sin embargo, si copias un directorio ya existente (incluso a uno "nuevo"), es posible que se preserve el estado anterior sin nombre corto.

Verificar con el comando FOR:

Puedes probar en una línea de comandos lo siguiente para ver si existe un nombre corto:

bat

Copiar

for %I in ("P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CMD INSERTADO EN VB6\") do echo %~sI

Si el resultado es el mismo path largo, significa que no se generó un alias corto.

No existe una actualización automática:

Windows no ofrece un mecanismo nativo para "regenerar" o actualizar de forma retroactiva todos los nombres cortos en el disco. Si necesitas que un directorio tenga un nombre corto, deberás crear uno nuevo (por ejemplo, usar mkdir desde la línea de comandos después de habilitar 8.3) o renombrarlo de manera que Windows genere un nuevo nombre corto.

En resumen, si necesitas trabajar con paths sin espacios en tus archivos BAT, tendrás que asegurarte de que los directorios se creen después de habilitar la generación de nombres cortos o considerar otra solución, como envolver las rutas en comillas cuando se usen en comandos BAT.

o3-mini-high

Dijiste:

Ok

ChatGPT dijo:

Razonado durante un par de segundos

De acuerdo. Si necesitas más ayuda o tienes alguna otra consulta, ¡aquí estaré!

o3-mini-high

Dijiste:

Ok, este es el bat que he creado:
////////////////
@echo off
Rem Usa %~1 para quitar comillas extra del primer argumento y lo envuelve en comillas.
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 "%~1" > P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CREATE MORPH AUTOMATIC2\GetVideoInfo.txt
////////////////

Pero claro, no le he indicado el video de referencia que tiene que dar los datos

ChatGPT dijo:

Razonado durante 7 segundos

El BAT que has creado está diseñado para recibir la ruta del archivo de video como primer argumento (usando %~1). Es decir, cuando ejecutes el BAT debes pasarle la ruta del video que quieres analizar. Por ejemplo, si tu BAT se llama GetVideoInfo.bat, lo llamarías de esta forma desde la línea de comandos:

bat

Copiar

GetVideoInfo.bat "C:\ruta\video.mp4"

De esta manera, %~1 se expandirá a "C:\ruta\video.mp4" y ffprobe usará ese archivo para extraer la información, redirigiéndola al archivo GetVideoInfo.txt.

Si lo estás llamando desde VB6 con CreateProcess o similar, asegúrate de construir la línea de comandos incluyendo el BAT y el argumento, por ejemplo:

vb

Copiar

cmd.exe /c "C:\ruta\GetVideoInfo.bat" "C:\ruta\video.mp4"

Así, el BAT recibirá la ruta del video y procesará el archivo correspondiente.

o3-mini-high

Dijiste:

Es que yo uso process pipes, y llamo asi:
cmdLine = Environ$("COMSPEC") & " /C """ & Glb_PathVideo$ & """"

ChatGPT dijo:

Razonado durante 6 segundos

Para que el BAT reciba el video como parámetro, debes incluir en la línea de comandos la ruta del BAT y, a continuación, la ruta del video. Por ejemplo, si el BAT se llama GetVideoInfo.bat y está en:

sql

Copiar

P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CREATE MORPH AUTOMATIC2\GetVideoInfo.bat

Entonces tu línea de comandos en VB6 debería ser algo así:

vb

Copiar

cmdLine = Environ$("COMSPEC") & " /C " & _
"""P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CREATE MORPH AUTOMATIC2\GetVideoInfo.bat""" & _
" """ & Glb_PathVideo$ & """"

Este comando hace lo siguiente:

Llama a cmd.exe usando /C para ejecutar un comando.

El primer argumento entre comillas es la ruta completa del BAT.

El segundo argumento es la ruta del video (Glb_PathVideo$), también entre comillas para manejar espacios.

De esta forma, el BAT recibirá el path del video en %~1 y ejecutará el comando ffprobe con ese parámetro, redirigiendo la salida al archivo GetVideoInfo.txt.

o3-mini-high

Dijiste:

Si le pongo:
cmdLine = Environ$("COMSPEC") & " /C " & """P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CREATE~2\GETVID~1.BAT""" & " """ & "C:\ALINAV~2.MP4" & """"

Me dice el process pipe:
"P:\idsjt\PhysX\files\Engine\imbnsjh5\New" no se reconoce como un comando interno o externo,
programa o archivo por lotes ejecutable.

[Proceso finalizado]

ChatGPT dijo:

Razonado durante 17 segundos

El error que ves se debe a que, aunque ya estás usando comillas, el sistema interpreta que la ruta del BAT se corta en el primer espacio. En otras palabras, la ruta no está completamente en formato short, y por eso se está dividiendo en "P:\idsjt\PhysX\files\Engine\imbnsjh5\New" y el resto.

Para solucionarlo tienes dos opciones:

Obtener el short path completo:

Usa la función GetShortPathName en VB6 para convertir la ruta completa del BAT (incluyendo todos los directorios con espacios) a su versión 8.3. Por ejemplo, en lugar de:

sql

Copiar

P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CREATE~2\GETVID~1.BAT

deberías obtener algo como:

css

Copiar

P:\idsjt\PhysX\files\Engine\imbnsjh5\NEWCOD~1\CREATE~2\GETVID~1.BAT

(si ese es el short name real para "New Codigos Vb6"). Esto garantiza que la ruta no tenga espacios y se pueda interpretar correctamente.

Asegurarte de que las comillas estén correctamente ubicadas:

Aunque ya usas comillas, verifica que la línea de comando se esté formando correctamente. Por ejemplo, podrías construirla así:

vb

Copiar

cmdLine = Environ$("COMSPEC") & " /C " & _
"""P:\idsjt\PhysX\files\Engine\imbnsjh5\New Codigos Vb6\CREATE~2\GETVID~1.BAT""" & " " & _
"""C:\ALINAV~2.MP4"""

Sin embargo, si la ruta del BAT contiene espacios, lo ideal es obtener la versión short completa, ya que de lo contrario el intérprete de comandos (cmd.exe) puede romper la línea en partes.

En resumen, la recomendación es convertir la ruta completa del BAT a su formato short usando GetShortPathName, de modo que no existan espacios en ningún directorio. De esa forma, al construir la línea de comandos, cmd.exe reconocerá correctamente el archivo a ejecutar.

o3-mini-high

Dijiste:

Pero convierte los ultimos directorios del path, los anteriores, como:
New Codigos Vb6

como estaban antes de activar:
fsutil 8dot3name set P: 0

No los convierte... Bueno, tendre que hacer todo desde un directorio nuevo desde el raiz del disco P:!!!

ChatGPT dijo:

Razonado durante unos segundos

Efectivamente, si los directorios fueron creados antes de habilitar la generación de nombres 8.3, es probable que no tengan asignado un nombre corto, ya que Windows no los genera retroactivamente. La función GetShortPathName solo devuelve un alias corto si éste existe.

Para que un directorio obtenga un nombre corto, tendrías que recrearlo o renombrarlo de forma que Windows genere un alias nuevo. Una solución práctica es crear un nuevo directorio en el raíz de la unidad P: (o en una ubicación donde la generación de nombres 8.3 esté activa desde el inicio) y mover allí tus archivos y carpetas, de modo que se asignen los nombres cortos correctamente.

Otra alternativa es usar un script que, de alguna manera, fuerce la recreación de dichos directorios, pero eso puede ser complejo y conllevar riesgos. Por lo tanto, si te resulta más sencillo, usar un directorio nuevo desde la raíz del disco P: es la opción más segura.

o3-mini-high

Dijiste:

Y si creo un directorio nuevo en el raiz del disco p, por ejemplo P:\AAA, y le muevo todo desde P:\idsjt\PhysX\files\Engine\imbnsjh5\

Luego borro el directorio imbnsjh5, y lo vuelvoa crear, y le muevo todos los archivos desde P:\AAA, me recreara los nombres cortos?

ChatGPT dijo:

Razonado durante 11 segundos

Exacto, el proceso que describes puede funcionar, pero hay un detalle importante:

Directorios nuevos:

Si creas un directorio nuevo en el raíz del disco (por ejemplo, P:\AAA) después de haber habilitado la creación de nombres 8.3, ese directorio se creará con su correspondiente nombre corto.

Archivos y subdirectorios existentes:

Los elementos que se crearon cuando la función estaba deshabilitada no tienen un nombre corto asignado.

Si simplemente los mueves (es decir, se renombrarán dentro del mismo volumen), Windows suele preservar el estado original y no se generan nuevos nombres cortos.

Si, en cambio, copias los archivos y directorios a un nuevo directorio (como P:\AAA) y luego eliminas los originales, los elementos copiados se crean de nuevo y, por lo tanto, se les asignarán nombres cortos automáticamente (siempre que la configuración de la unidad lo permita).

Por lo tanto, si deseas que todos los elementos tengan nombres cortos, la estrategia es:

Crear un directorio nuevo en la raíz, por ejemplo, P:\AAA.

Copiar (no mover) todos los archivos y subdirectorios desde *P:\idsjt\PhysX\files\Engine\imbnsjh5* a P:\AAA.

Borrar el directorio original (imbnsjh5) y recrearlo.

Copiar de vuelta los elementos desde P:\AAA al nuevo imbnsjh5 recién creado.

Con este proceso, todos los nuevos archivos y directorios se crean después de haber habilitado la generación de nombres cortos y, por lo tanto, se les asignará un alias 8.3 (siempre que se cumplan las condiciones del sistema).

Esta es la forma de forzar la regeneración de nombres cortos para esos elementos, ya que no se generan retroactivamente en un simple movimiento o renombrado dentro del mismo volumen.

o3-mini-high

Dijiste:

Ok, pues son mas de 2Tb, llevara tiempo jeje...

ChatGPT dijo:

Razonado durante unos segundos

Sí, con más de 2 TB de datos, el proceso de copiar y recrear los directorios puede llevar bastante tiempo. Te recomiendo planificar cuidadosamente la operación, quizá hacerlo en fases o durante periodos de baja actividad, para minimizar el impacto en el sistema.

o3-mini-high

Dijiste:

Ok chat, en parte arreglado, el bat es asi:
//////////////////////
@echo off
Rem Usa %~1 para quitar comillas extra del primer argumento y lo envuelve en comillas.
ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 C:\ALINAV~2.MP4
pause
/////////////////////

Y me da como resultado:
h264
512
512
30/1
23.233333
Presione una tecla para continuar . . .

El 30/1 me imagino que es el FPS

Pero el 23.233333 a que se refiere?

ChatGPT dijo:

Razonado durante 15 segundos

El valor 23.233333 corresponde a la duración del video en segundos. En otras palabras, el video dura aproximadamente 23.23 segundos.

El comando de ffprobe que usas está extrayendo varios parámetros del stream de video en este orden:

codec_name: "h264"

width: 512

height: 512

avg_frame_rate: "30/1" (equivalente a 30 FPS)

duration: 23.233333 (duración en segundos)

Si deseas mayor precisión o interpretar estos valores, ten en cuenta que el campo duration provisto es en segundos y puede incluir decimales para indicar fracciones de segundo.

o3-mini-high

Dijiste:

Se podria hacer que el bat de como resultado asi:
codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duración en segundos)

?

ChatGPT dijo:

Razonado durante 20 segundos

Sí, es posible formatear la salida para que se muestre con etiquetas. Una forma de hacerlo es capturar cada línea que devuelve ffprobe en variables (usando un bucle FOR) y luego mostrarlas con el formato deseado. Por ejemplo, podrías crear un BAT así:

bat

Copiar

@echo off
setlocal enabledelayedexpansion

REM Inicializamos el contador.
set count=0

REM Ejecuta ffprobe y captura las cinco líneas de salida.
for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 "C:\ALINAV~2.MP4"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

REM Muestra la información formateada.
echo codec_name: "\"!codec!\""
echo width: !width!
echo height: !height!
echo avg_frame_rate: "\"!frate!\"" (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)
pause

Cómo funciona el BAT:

Captura de salida:

Se ejecuta ffprobe con los parámetros indicados. Con la opción -of default=noprint_wrappers=1:nokey=1 se suprimen las envolturas y las etiquetas, de modo que se obtienen solo los valores en líneas separadas.

El bucle for /f recorre cada línea y las asigna a variables según el orden:

Línea 1: codec

Línea 2: width

Línea 3: height

Línea 4: frate

Línea 5: duration

Formato de salida:

Luego se usa echo para imprimir cada valor con la etiqueta deseada. En el caso de codec_name y avg_frame_rate se agregan comillas alrededor del valor usando \".

Pausa:

Se utiliza pause para mantener la ventana abierta y poder ver la salida.

De esta forma, al ejecutar el BAT verás una salida similar a:

vbnet

Copiar

codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duración en segundos)
Presione una tecla para continuar . . .

Asegúrate de ajustar la ruta del archivo de video según tu caso. Esta solución permite formatear la salida de ffprobe en el BAT de la manera que deseas.

o3-mini-high

Dijiste:

Pero no quiero que redirecione a un archivo, pues estoy usando process pipe que me muestra el resultado en un textbox de vb6

ChatGPT dijo:

Razonado durante 12 segundos

Aquí te dejo un ejemplo de BAT que formatea la salida de ffprobe sin redireccionarla a un archivo, de modo que se imprima en la salida estándar (y puedas capturar ese texto con tus pipes en VB6):

bat

Copiar

@echo off
setlocal enabledelayedexpansion

REM Verifica que se haya pasado un argumento (la ruta del video)
if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

set count=0

REM Ejecuta ffprobe y procesa la salida formateada
for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,avg_frame_rate,duration -of default=noprint_wrappers=1:nokey=1 "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

REM Imprime la salida formateada
echo codec_name: "\"!codec!\""
echo width: !width!
echo height: !height!
echo avg_frame_rate: "\"!frate!\"" (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

endlocal

Cómo funciona:

El BAT espera recibir la ruta del archivo de video como argumento (por ejemplo, al llamar:

GetVideoInfo.bat "C:\ruta\video.mp4").

Se utiliza un bucle for /f para leer la salida de ffprobe, asignando cada línea a una variable:

Línea 1: codec

Línea 2: width

Línea 3: height

Línea 4: frate (la tasa de frames)

Línea 5: duration (duración en segundos)

Luego se imprime la información con etiquetas y comillas donde lo deseas.

Con este BAT, la salida se mostrará en la consola y, al ejecutarlo desde VB6 mediante tus pipes, podrás capturar esa salida y mostrarla en el textbox sin necesidad de redireccionar a un archivo.

o3-mini-high

Dijiste:

El bat que me has hecho dice esto:

codec_name: "\"\""
width:
height:
avg_frame_rate: "\"\"" (equivalente a 30 FPS)
duration: (duraciÃ³n en segundos)
Presione una tecla para continuar . . . Argument 'width' provided as input filename, but 'codec_name' was already specified.

ChatGPT dijo:

Razonado durante 9 segundos

El error se debe a que ffprobe interpreta mal el parámetro del formato de salida. La opción -of default=noprint_wrappers=1:nokey=1 contiene dos puntos y otros caracteres que hacen que ffprobe confunda parte de la cadena como argumentos o nombres de archivo. La solución es encerrar ese parámetro entre comillas para que se pase como un único argumento.

Prueba con este BAT actualizado:

bat

Copiar

@echo off
setlocal enabledelayedexpansion

REM Verifica que se haya pasado un argumento (la ruta del video)
if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

set count=0

REM Ejecuta ffprobe con el parámetro -of entre comillas
for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,avg_frame_rate,duration -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

REM Imprime la salida formateada
echo codec_name: "\"!codec!\""
echo width: !width!
echo height: !height!
echo avg_frame_rate: "\"!frate!\"" (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

endlocal

Explicación

Se verifica que se reciba la ruta del video como argumento.

Se usa un bucle for /f para capturar cada línea de salida de ffprobe.

Se asignan las líneas a las variables codec, width, height, frate y duration.

La opción -of se pasa como -of "default=noprint_wrappers=1:nokey=1" para evitar que ffprobe interprete parte de la cadena como un nombre de archivo.

Finalmente, se imprime la información formateada en la salida estándar, la cual puedes capturar desde tu proceso pipe en VB6.

Con este ajuste, deberías obtener la salida correctamente sin el error:

vbnet

Copiar

codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duración en segundos)

o3-mini-high

Dijiste:

Estoy en VB6, y el nuevo Bat me dice:
codec_name: "\"\""
width:
height:
avg_frame_rate: "\"\"" (equivalente a 30 FPS)
duration: (duraciÃ³n en segundos)
Argument 'width' provided as input filename, but 'codec_name' was already specified.

[Proceso finalizado]

ChatGPT dijo:

Razonado durante 10 segundos

El error se debe a que ffprobe está interpretando la lista de elementos de -show_entries de forma separada. Para evitarlo, es necesario encerrar todo el parámetro (la parte que indica qué elementos mostrar) entre comillas, de modo que se pase como un único argumento.

Prueba actualizando la línea de ffprobe en el BAT de esta forma:

bat

Copiar

ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"

Quedando el BAT completo así:

bat

Copiar

@echo off
setlocal enabledelayedexpansion

if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

set count=0

for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

echo codec_name: "\"!codec!\""
echo width: !width!
echo height: !height!
echo avg_frame_rate: "\"!frate!\"" (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

endlocal

Explicación

-show_entries "stream=codec_name,width,height,avg_frame_rate,duration"

Al poner toda la cadena entre comillas, evitas que ffprobe interprete la coma o el espacio como separadores de argumentos. Así se procesa la lista completa como un solo parámetro.

-of "default=noprint_wrappers=1:nokey=1"

Esta opción ya estaba entre comillas, lo cual es correcto.

Con este cambio, la salida debería quedar correctamente formateada y sin errores, y podrás capturar la salida en tu proceso pipe en VB6 sin redireccionar a un archivo.

o3-mini-high

Dijiste:

Va quedando mejor, aunque aun poe algunos \:
codec_name: "\"h264\""
width: 512
height: 512
avg_frame_rate: "\"30/1\"" (equivalente a 30 FPS)
duration: 23.233333 (duraciÃ³n en segundos)

[Proceso finalizado]

ChatGPT dijo:

Razonado durante 11 segundos

Para que la salida se muestre con una sola pareja de comillas en lugar de cadenas con escapes, puedes definir una variable que contenga el carácter de comilla y usarla en el echo. Por ejemplo, modifica el BAT así:

bat

Copiar

@echo off
setlocal enabledelayedexpansion

REM Define una variable que contiene el carácter de comilla
set q="

if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

set count=0

for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

echo codec_name: !q!!codec!!q!
echo width: !width!
echo height: !height!
echo avg_frame_rate: !q!!frate!!q! (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

endlocal

Explicación

Definir la variable q:

Se crea la variable q que contiene solo una comilla ("). Esto te permite construir la salida colocando !q! antes y después de la variable que contiene el dato, de forma que se muestre, por ejemplo, "h264" sin que aparezcan barras invertidas.

El resto del BAT:

Se ejecuta ffprobe con los parámetros correctos y se asignan las líneas a las variables codec, width, height, frate y duration.

Luego, se muestra la información formateada usando la variable q para delimitar los valores que quieres que aparezcan entre comillas.

Con esta modificación la salida debería verse así:

vbnet

Copiar

codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duración en segundos)

De esta forma, al capturar la salida en tu TextBox de VB6 mediante process pipes, obtendrás el formato deseado sin los caracteres de escape adicionales.

o3-mini-high

Dijiste:

Y por perfeccion, se podria cambiar el duraciÃ³n en segundos, por duración en segundos:
codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duraciÃ³n en segundos)

[Proceso finalizado]

ChatGPT dijo:

Razonado durante 10 segundos

Para que la salida muestre correctamente el acento (ó) en "duración en segundos", puedes forzar la página de códigos adecuada al inicio del BAT. Por ejemplo, si usas la página de códigos 1252 (Windows-1252), agrega la línea:

bat

Copiar

chcp 1252 > nul

Así el BAT completo quedaría:

bat

Copiar

@echo off
chcp 1252 > nul
setlocal enabledelayedexpansion

if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

set count=0

for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

echo codec_name: !q!!codec!!q!
echo width: !width!
echo height: !height!
echo avg_frame_rate: !q!!frate!!q! (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

endlocal

Si además ya definiste la variable q para las comillas, asegúrate de incluirla antes de usarla, por ejemplo:

bat

Copiar

set q="

Quedando el BAT final de la siguiente manera:

bat

Copiar

@echo off
chcp 1252 > nul
setlocal enabledelayedexpansion

set q="

if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

set count=0

for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

echo codec_name: !q!!codec!!q!
echo width: !width!
echo height: !height!
echo avg_frame_rate: !q!!frate!!q! (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

endlocal

Con este ajuste, la salida debería mostrar:

vbnet

Copiar

codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duración en segundos)

Asegúrate de guardar el archivo BAT en una codificación que sea compatible con la página de códigos (por ejemplo, ANSI o Windows-1252) para evitar problemas de caracteres.

o3-mini-high

Dijiste:

Sigue dando lo mismo:
codec_name: h264
width: 512
height: 512
avg_frame_rate: 30/1 (equivalente a 30 FPS)
duration: 23.233333 (duraciÃ³n en segundos)

[Proceso finalizado]

ChatGPT dijo:

Reasoned about command batch script durante 16 segundos

El problema se debe a un desajuste entre la codificación en la que está guardado el archivo BAT y la página de códigos que usa la consola. Para que se muestre "duración" correctamente, debes asegurarte de lo siguiente:

Guardar el BAT en la codificación correcta:

Guarda el archivo BAT en formato ANSI (Windows-1252) en lugar de UTF-8. Si usas el Bloc de notas, elige "Guardar como" y selecciona "ANSI" en el campo de codificación.

Establecer la página de códigos adecuada en la consola:

Si el archivo está en ANSI, el comando

bat

Copiar

chcp 1252 > nul

es correcto. Esto hace que la consola use la página de códigos Windows-1252, que es compatible con los caracteres acentuados en español.

Con estos dos pasos, la salida debería aparecer así:

vbnet

Copiar

codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duración en segundos)

Si aún así sigues viendo "duraciÃ³n" en lugar de "duración", revisa:

Que el archivo BAT realmente esté guardado en ANSI (puedes abrirlo con un editor de texto que te permita ver la codificación).

Que no haya ningún otro factor en tu entorno (por ejemplo, la configuración regional de Windows) que interfiera con la codificación.

Otra alternativa es usar UTF-8, pero en ese caso deberías forzar la consola a usar UTF-8 con:

bat

Copiar

chcp 65001 > nul

y asegurarte de que el BAT esté guardado en UTF-8 sin BOM (o con BOM si la consola lo reconoce bien), aunque esto puede ser menos predecible en versiones antiguas de Windows.

La opción recomendada es usar ANSI con chcp 1252 y guardar el BAT en ANSI para evitar problemas de caracteres.

o3-mini-high

Dijiste:

Bueno, era por perfeccionar, pero puedo hacer un replace de:
Ã³
Por ó

No es gran problema...

ChatGPT dijo:

Razonado durante un par de segundos

Exacto, puedes solucionar el problema haciendo un replace en VB6 para cambiar "Ã³" por "ó". Por ejemplo:

vb

Copiar

Dim salidaFormateada As String
salidaFormateada = Replace(textoOriginal, "Ã³", "ó")

De este modo, se reemplazan los caracteres incorrectos y se muestra correctamente "duración" en tu TextBox.

o3-mini-high

Dijiste:

Ok, ahora otra cosa, se podria incluir en el Bat que sacara la primera imagen del video y la ultima imagen del video, con ffmpeg?

Es que ayer estuvimos en otro chat mirando de hacer un morph entre videos de Hedra, y como habia varios parametros que se podian modificar en el py de morph:
///////////////////
'parser.add_argument('--src', required=True, help='Ruta a la imagen fuente (ej. C:\\imagen1.jpg)')
'parser.add_argument('--dest', required=True, help='Ruta a la imagen destino (ej. C:\\imagen2.jpg)')
'parser.add_argument('--frames', type=int, default=30, help='Número de fotogramas intermedios')
'parser.add_argument('--output', required=True, help='Ruta al video de salida (ej. C:\\salida2.mp4)')
'parser.add_argument('--predictor', required=True, help='Ruta al archivo del predictor dlib (ej. shape_predictor_68_face_landmarks.dat)')
'parser.add_argument('--orbfeatures', type=int, default=500, help='Número máximo de características ORB')
'parser.add_argument('--ransac', type=float, default=5.0, help='Umbral de reproyección RANSAC')
'parser.add_argument('--edgestep', type=int, default=50, help='Salto para añadir puntos en bordes')
'parser.add_argument('--marginface', type=int, default=0, help='Margen para excluir puntos ORB dentro de la cara')
'parser.add_argument('--fps', type=int, default=30, help='FPS de salida del video')
///////////////////

Lo estuve pensando y estoy haciendo un programita en VB6, que le pueda indicar el video 1 y el video 2 y ejecutar el morph, para ello necesito que sacar la primera y la ultima imagen de cada video, pues son 2 videos que tengo que hacerles un morph en medio.

Entonces, dentro de ese mismo bat, se podria ya ejecutar un ffmpeg que saque la primera imagen del video y la ultima, y las salve en png?

ChatGPT dijo:

Razonado durante 8 segundos

Sí, se puede incluir en el mismo BAT la ejecución de ffmpeg para extraer tanto la primera como la última imagen del video y guardarlas en formato PNG. Por ejemplo, podrías extender tu BAT de la siguiente forma:

bat

Copiar

@echo off
chcp 1252 > nul
setlocal enabledelayedexpansion

if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

REM --- Extraer información del video con ffprobe ---
set count=0
for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

echo codec_name: "!codec!"
echo width: !width!
echo height: !height!
echo avg_frame_rate: "!frate!" (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

REM --- Extraer la primera imagen (primer frame) ---
ffmpeg -y -i "%~1" -vf "select=eq(n\,0)" -q:v 3 "first_frame.png"

REM --- Extraer la última imagen (último frame) ---
ffmpeg -y -sseof -0.1 -i "%~1" -update 1 -q:v 3 "last_frame.png"

endlocal

Explicación de los comandos de extracción:

Extraer el primer frame:

bat

Copiar

ffmpeg -y -i "%~1" -vf "select=eq(n\,0)" -q:v 3 "first_frame.png"

Esta línea le indica a ffmpeg que abra el video (la ruta se recibe como %~1), seleccione el primer frame (donde el contador de frames n es 0) y lo guarde en formato PNG (con calidad de imagen controlada por -q:v 3).

Extraer el último frame:

bat

Copiar

ffmpeg -y -sseof -0.1 -i "%~1" -update 1 -q:v 3 "last_frame.png"

Con la opción -sseof -0.1, ffmpeg busca 0.1 segundos desde el final del archivo. Luego se extrae un único frame (-update 1) y se guarda como "last_frame.png".

(Este método funciona en versiones recientes de ffmpeg; si tu versión es antigua, podría necesitarse otro enfoque.)

Uso desde VB6

Al llamar a este BAT desde VB6 mediante tu proceso pipe, simplemente debes pasarle la ruta del video como argumento. Por ejemplo, si la ruta del video está en la variable Glb_PathVideo$, la línea de comando en VB6 podría quedar:

vb

Copiar

cmdLine = Environ$("COMSPEC") & " /C " & _
"""ruta_completa_al_BAT\GetVideoInfo.bat""" & " " & _
"""" & Glb_PathVideo$ & """"

De esta manera, el BAT extraerá la información del video y generará dos archivos PNG, uno con el primer frame y otro con el último frame, que luego podrás usar en tu proceso de morph.

Con estos ajustes, tendrás todo integrado en un único BAT que podrás invocar desde VB6.

o3-mini-high

Dijiste:

Me dice esto:
codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duraciÃ³n en segundos)
ffmpeg version 7.1-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\ALINAV~2.MP4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:00:23.23, start: 0.000000, bitrate: 2177 kb/s
Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 512x512 [SAR 1:1 DAR 1:1], 2100 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 69 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> png (native))
Press [q] to stop, [?] for help
Output #0, image2, to 'first_frame.png':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf61.7.100
Stream #0:0(und): Video: png, rgb24(pc, gbr/unknown/unknown, progressive), 512x512 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 30 fps, 30 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc61.19.100 png
[image2 @ 000001806d6ecd80] The specified filename 'first_frame.png' does not contain an image sequence pattern or a pattern is invalid.
[image2 @ 000001806d6ecd80] Use a pattern such as %03d for an image sequence or use the -update option (with -frames:v 1 if needed) to write a single image.
[out#0/image2 @ 000001806d810c40] video:331KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
frame= 1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.03 bitrate=N/A speed=0.249x
ffmpeg version 7.1-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\ALINAV~2.MP4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:00:23.23, start: 0.000000, bitrate: 2177 kb/s
Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 512x512 [SAR 1:1 DAR 1:1], 2100 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 69 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> png (native))
Press [q] to stop, [?] for help
Output #0, image2, to 'last_frame.png':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf61.7.100
Stream #0:0(und): Video: png, rgb24(pc, gbr/unknown/unknown, progressive), 512x512 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 30 fps, 30 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc61.19.100 png
[out#0/image2 @ 0000015998f50c40] video:1217KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
frame= 3 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.10 bitrate=N/A speed=1.06x

[Proceso finalizado]

ChatGPT dijo:

Razonado durante 16 segundos

Para resolver el error que indica que el nombre de archivo no contiene un patrón de secuencia de imágenes, debes indicarle a ffmpeg que solo genere un único frame usando la opción -frames:v 1. Esto le dice a ffmpeg que no espere una secuencia numerada, sino que simplemente escriba una única imagen.

Por ejemplo, puedes modificar la línea para extraer el primer frame de la siguiente manera:

bat

Copiar

ffmpeg -y -i "%~1" -vf "select=eq(n\,0)" -frames:v 1 -q:v 3 "first_frame.png"

Y para el último frame, también es recomendable agregar -frames:v 1 junto con -update 1:

bat

Copiar

ffmpeg -y -sseof -0.1 -i "%~1" -frames:v 1 -update 1 -q:v 3 "last_frame.png"

Un BAT completo que haga todo (extraer información y luego las imágenes) quedaría así:

bat

Copiar

@echo off
chcp 1252 > nul
setlocal enabledelayedexpansion

if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

set count=0
for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

echo codec_name: "!codec!"
echo width: !width!
echo height: !height!
echo avg_frame_rate: "!frate!" (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)

REM Extrae el primer frame (imagen) usando -frames:v 1 para generar una única imagen.
ffmpeg -y -i "%~1" -vf "select=eq(n\,0)" -frames:v 1 -q:v 3 "first_frame.png"

REM Extrae el último frame usando -sseof -0.1 y -frames:v 1 junto con -update 1 para sobrescribir.
ffmpeg -y -sseof -0.1 -i "%~1" -frames:v 1 -update 1 -q:v 3 "last_frame.png"

endlocal

Con estas modificaciones, ffmpeg generará first_frame.png y last_frame.png sin esperar un patrón de secuencia de imágenes. Luego podrás capturar toda la salida (sin redirección a archivo) en tu proceso pipe en VB6.

o3-mini-high

Dijiste:

Me dice esto, no se si las ha salvado, en el directorio dodne reside el programa no estan:
codec_name: "h264"
width: 512
height: 512
avg_frame_rate: "30/1" (equivalente a 30 FPS)
duration: 23.233333 (duraciÃ³n en segundos)
ffmpeg version 7.1-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\ALINAV~2.MP4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:00:23.23, start: 0.000000, bitrate: 2177 kb/s
Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 512x512 [SAR 1:1 DAR 1:1], 2100 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 69 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> png (native))
Press [q] to stop, [?] for help
Output #0, image2, to 'first_frame.png':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf61.7.100
Stream #0:0(und): Video: png, rgb24(pc, gbr/unknown/unknown, progressive), 512x512 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 30 fps, 30 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc61.19.100 png
[image2 @ 000001cf582bcb40] The specified filename 'first_frame.png' does not contain an image sequence pattern or a pattern is invalid.
[image2 @ 000001cf582bcb40] Use a pattern such as %03d for an image sequence or use the -update option (with -frames:v 1 if needed) to write a single image.
[out#0/image2 @ 000001cf583e0c40] video:331KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
frame= 1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.03 bitrate=N/A speed=1.46x
ffmpeg version 7.1-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libopenjpeg --enable-libquirc --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-libqrencode --enable-librav1e --enable-libsvtav1 --enable-libvvenc --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-liblc3 --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 59. 39.100 / 59. 39.100
libavcodec 61. 19.100 / 61. 19.100
libavformat 61. 7.100 / 61. 7.100
libavdevice 61. 3.100 / 61. 3.100
libavfilter 10. 4.100 / 10. 4.100
libswscale 8. 3.100 / 8. 3.100
libswresample 5. 3.100 / 5. 3.100
libpostproc 58. 3.100 / 58. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\ALINAV~2.MP4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:00:23.23, start: 0.000000, bitrate: 2177 kb/s
Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 512x512 [SAR 1:1 DAR 1:1], 2100 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 69 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> png (native))
Press [q] to stop, [?] for help
Output #0, image2, to 'last_frame.png':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf61.7.100
Stream #0:0(und): Video: png, rgb24(pc, gbr/unknown/unknown, progressive), 512x512 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 30 fps, 30 tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
encoder : Lavc61.19.100 png
[out#0/image2 @ 000002b9fb0a0c40] video:405KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
frame= 1 fps=0.0 q=-0.0 Lsize=N/A time=00:00:00.03 bitrate=N/A speed=0.305x

[Proceso finalizado]

ChatGPT dijo:

Razonado durante 16 segundos

El mensaje indica que ffmpeg espera un patrón de secuencia de imágenes, ya que sin él trata de generar una secuencia de archivos. Para que genere una única imagen en lugar de una secuencia, debes agregar la opción -update 1 también en la línea para el primer frame. Es decir, cambia la línea de extracción del primer frame a:

bat

Copiar

ffmpeg -y -i "%~1" -vf "select=eq(n\,0)" -frames:v 1 -update 1 -q:v 3 "first_frame.png"

Esto le indica a ffmpeg que, en lugar de buscar un patrón de salida (como %03d), simplemente sobrescriba (o escriba) el archivo first_frame.png con ese único frame.

Consejos adicionales:

Verifica que el directorio de trabajo actual (donde se guarda la imagen) sea el que esperas. Si no, puedes especificar una ruta completa para los archivos, por ejemplo, "C:\Ruta\Output\first_frame.png".

Si el comando para el último frame ya funciona, solo debes ajustar el de la primera imagen de forma similar.

Con ese cambio, el BAT debería crear correctamente first_frame.png y last_frame.png en el directorio esperado.

o3-mini-high

Dijiste:

Pero en esta linea, donde le especificas que video es del que tiene que sacar las imagenes?

ffmpeg -y -i "%~1" -vf "select=eq(n\,0)" -frames:v 1 -update 1 -q:v 3 "first_frame.png"

ChatGPT dijo:

Razonado durante unos segundos

La opción -i "%~1" le dice a ffmpeg cuál es el archivo de entrada. En un BAT, %~1 representa el primer argumento que le pases al script. Por ejemplo, si ejecutas:

bat

Copiar

GetVideoInfo.bat "C:\ruta\video.mp4"

entonces %~1 se expandirá a "C:\ruta\video.mp4", indicándole a ffmpeg que debe extraer imágenes de ese video.

o3-mini-high

Dijiste:

Para no liarme, me podrias dar el bat completo con esa linea?

ChatGPT dijo:

Razonado durante 5 segundos

Aquí tienes el BAT completo, que extrae la información del video con ffprobe y luego extrae la primera y última imagen usando ffmpeg. Recuerda que %~1 es el primer argumento que le pases al BAT (la ruta del video):

bat

Copiar

@echo off
chcp 1252 >nul
setlocal enabledelayedexpansion

REM Verifica que se haya proporcionado un archivo de video como argumento.
if "%~1"=="" (
echo No se ha especificado el archivo de video.
goto :EOF
)

REM --- Extraer información del video con ffprobe ---
set count=0
for /f "usebackq tokens=*" %%a in (`ffprobe -v error -select_streams v:0 -show_entries "stream=codec_name,width,height,avg_frame_rate,duration" -of "default=noprint_wrappers=1:nokey=1" "%~1"`) do (
set /a count+=1
if !count! equ 1 set codec=%%a
if !count! equ 2 set width=%%a
if !count! equ 3 set height=%%a
if !count! equ 4 set frate=%%a
if !count! equ 5 set duration=%%a
)

echo codec_name: "!codec!"
echo width: !width!
echo height: !height!
echo avg_frame_rate: "!frate!" (equivalente a 30 FPS)
echo duration: !duration! (duración en segundos)
echo.

REM --- Extraer la primera imagen (primer frame) ---
ffmpeg -y -i "%~1" -vf "select=eq(n\,0)" -frames:v 1 -update 1 -q:v 3 "first_frame.png"

REM --- Extraer la última imagen (último frame) ---
ffmpeg -y -sseof -0.1 -i "%~1" -frames:v 1 -update 1 -q:v 3 "last_frame.png"

endlocal

Cómo usar este BAT

Guarda el contenido anterior en un archivo, por ejemplo, GetVideoData.bat.

Desde VB6 (o desde la línea de comandos) ejecútalo pasando la ruta del video como argumento. Por ejemplo:

bat

Copiar

GetVideoData.bat "C:\ruta\video.mp4"

El BAT usará ese archivo como entrada para extraer la información y generar los archivos first_frame.png y last_frame.png en el directorio de trabajo actual.

o3-mini-high

Buscar

Investigar a fondo

ChatGPT puede cometer errores. Comprueba la información importante.

?