# Ejecutar como Administrador en Windows: # $ irm https://getwin.demedallo.com | iex param( [switch]$SkipAdminCheck ) # ======================================== # 1. Verificación de privilegios (CORREGIDO) # ======================================== function Test-IsAdmin { if ($PSVersionTable.PSEdition -eq 'Core' -and ($IsLinux -or $IsMacOS)) { return (id -u 2>$null) -eq 0 } else { $currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent() ) return $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } } if (-not $SkipAdminCheck -and -not (Test-IsAdmin)) { Write-Host "`n❌ Este script requiere privilegios de Administrador." -ForegroundColor Red Write-Host " ➜ Click derecho en PowerShell → 'Ejecutar como administrador'`n" -ForegroundColor Yellow Start-Sleep -Seconds 3 exit 1 } # ======================================== # 2. Obtener información del sistema # ======================================== function Get-SystemInfo { $info = @{} if ($IsLinux -or $IsMacOS) { $info.Sistema = "Linux/MacOS" $info.Hostname = $(hostname 2>$null) $info.Kernel = $(uname -r 2>$null) $info.Arquitectura = $(uname -m 2>$null) $info.Usuario = $(whoami 2>$null) $info.IP = $(hostname -I 2>$null).Trim() } else { $computer = Get-ComputerInfo $info.Sistema = "Windows $($computer.WindowsProductName) $($computer.WindowsVersion)" $info.Hostname = $computer.CsName $info.Usuario = "$($computer.CsDomain)\$($computer.CsUserName)" $info.Arquitectura = $computer.CsSystemType $info.RAM_Total = "{0:N1} GB" -f ($computer.OsTotalVisibleMemorySize / 1MB) $disk = Get-PSDrive C -ErrorAction SilentlyContinue if ($disk) { $free = [math]::Round($disk.Free / 1GB, 2) $total = [math]::Round(($disk.Used + $disk.Free) / 1GB, 2) $info.Disco = "$free GB libres de $total GB" } $ip = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.InterfaceAlias -notlike '*Loopback*' -and $_.AddressState -eq 'Preferred' } | Select-Object -First 1 $info.IP = if ($ip) { $ip.IPAddress } else { "No disponible" } } return $info } # ======================================== # 3. Test de rendimiento del sistema (OPCIÓN 3) # ======================================== function Test-SystemPerformance { Clear-Host Write-Host "`n╔════════════════════════════════════════════════════════════╗" -ForegroundColor Magenta Write-Host "║ 3. Test de Rendimiento del Dispositivo ║" -ForegroundColor Magenta Write-Host "╚════════════════════════════════════════════════════════════╝`n" -ForegroundColor Magenta Write-Host "⏳ Analizando hardware...`n" -ForegroundColor Cyan Start-Sleep -Seconds 1 # Disco Duro Write-Host "💾 DISCO DURO" -ForegroundColor Yellow Write-Host ("─" * 55) -ForegroundColor DarkGray $disco = Get-PhysicalDisk | Select-Object -First 1 if ($disco) { $tipoDisco = switch ($disco.MediaType) { "SSD" { "SSD (rápido)" } "HDD" { "HDD (mecánico)" } default { $disco.MediaType } } Write-Host " Modelo : $($disco.FriendlyName)" -ForegroundColor White Write-Host " Tipo : $tipoDisco" -ForegroundColor White Write-Host " Capacidad : $([math]::Round($disco.Size / 1TB, 2)) TB" -ForegroundColor White } else { Write-Host " Información no disponible" -ForegroundColor Red } # Memoria RAM Write-Host "`n🧠 MEMORIA RAM" -ForegroundColor Yellow Write-Host ("─" * 55) -ForegroundColor DarkGray $ram = Get-CimInstance Win32_PhysicalMemory $totalRAM = ($ram | Measure-Object -Property Capacity -Sum).Sum / 1GB $slots = $ram.Count $velocidad = if ($ram -and $ram[0].ConfiguredClockSpeed) { "$($ram[0].ConfiguredClockSpeed) MHz" } else { "Desconocida" } Write-Host " Total : $([math]::Round($totalRAM, 1)) GB" -ForegroundColor White Write-Host " Slots usados : $slots" -ForegroundColor White Write-Host " Velocidad : $velocidad" -ForegroundColor White # Procesador Write-Host "`n⚙️ PROCESADOR (CPU)" -ForegroundColor Yellow Write-Host ("─" * 55) -ForegroundColor DarkGray $cpu = Get-CimInstance Win32_Processor | Select-Object -First 1 $nucleosTotales = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors Write-Host " Modelo : $($cpu.Name)" -ForegroundColor White Write-Host " Núcleos : $nucleosTotales lógicos" -ForegroundColor White Write-Host " Velocidad : $($cpu.MaxClockSpeed) MHz" -ForegroundColor White # Tarjeta Gráfica Write-Host "`n🎮 TARJETA GRÁFICA (GPU)" -ForegroundColor Yellow Write-Host ("─" * 55) -ForegroundColor DarkGray $gpu = Get-CimInstance Win32_VideoController | Select-Object -First 1 if ($gpu) { Write-Host " Modelo : $($gpu.Name)" -ForegroundColor White Write-Host " Memoria VRAM : $([math]::Round($gpu.AdapterRAM / 1GB, 1)) GB" -ForegroundColor White } else { Write-Host " Información no disponible" -ForegroundColor Red } # Puntaje Windows (WEI) Write-Host "`n⭐ PUNTUACIÓN WINDOWS (WEI)" -ForegroundColor Yellow Write-Host ("─" * 55) -ForegroundColor DarkGray $weiFile = Get-ChildItem "C:\Windows\Performance\WinSAT\DataStore\" -Filter "Formal.Assessment (*).WinSAT.xml" -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if ($weiFile) { try { [xml]$xml = Get-Content $weiFile.FullName $baseScore = $xml.WinSAT.WinSPR.BaseScore Write-Host " Puntuación Base : $baseScore / 10.0" -ForegroundColor Green # Subscores si existen $subs = @() if ($xml.WinSAT.WinSPR.CPUScore) { $subs += " └─ CPU : $($xml.WinSAT.WinSPR.CPUScore) / 10.0" } if ($xml.WinSAT.WinSPR.MemoryScore) { $subs += " └─ RAM : $($xml.WinSAT.WinSPR.MemoryScore) / 10.0" } if ($xml.WinSAT.WinSPR.GraphicsScore) { $subs += " └─ Gráficos : $($xml.WinSAT.WinSPR.GraphicsScore) / 10.0" } if ($xml.WinSAT.WinSPR.DiskScore) { $subs += " └─ Disco : $($xml.WinSAT.WinSPR.DiskScore) / 10.0" } $subs | ForEach-Object { Write-Host $_ -ForegroundColor White } Write-Host "`n ℹ️ Última evaluación: $($weiFile.LastWriteTime.ToString('dd/MM/yyyy'))" -ForegroundColor DarkGray } catch { Write-Host " ⚠️ Puntuación disponible pero no legible" -ForegroundColor Yellow } } else { Write-Host " ⚠️ No disponible en Windows 10/11" -ForegroundColor Yellow Write-Host " 💡 Ejecutando 'winsat formal' como Admin" -ForegroundColor Cyan winsat formal Write-Host " ⏱️ (El test tarda 5-10 minutos)" -ForegroundColor Red } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor DarkGray Read-Host | Out-Null } # ======================================== # 4. Mostrar menú principal # ======================================== function Show-Menu { Clear-Host Write-Host "`n╔════════════════════════════════════════════════╗" -ForegroundColor Cyan Write-Host "║ Herramientas del Sistema v0.1 ║" -ForegroundColor Cyan Write-Host "║ ----------------------------- ║" -ForegroundColor Cyan Write-Host "║ Powered By FelipheGomez - deMedallo.com ║" -ForegroundColor Cyan Write-Host "╚════════════════════════════════════════════════╝" -ForegroundColor Cyan Write-Host "`n📋 Menú de opciones:" Write-Host " ┌───────────────────────────────────────────────┐" -ForegroundColor DarkGray Write-Host " │ │" -ForegroundColor Yellow Write-Host " │ 1. Hello World! │" -ForegroundColor Yellow Write-Host " │ │" -ForegroundColor Yellow Write-Host " │ 2. Información básica del sistema │" -ForegroundColor Yellow Write-Host " │ 3. Test de rendimiento │" -ForegroundColor Yellow Write-Host " │ 4. Verificar velocidad del adaptador │" -ForegroundColor Yellow Write-Host " │ │" -ForegroundColor Yellow Write-Host " │ 51. Activador massgrave │" -ForegroundColor Yellow Write-Host " │ 52. Set-ExecutionPolicy (CurrentUser) │" -ForegroundColor Yellow Write-Host " │ │" -ForegroundColor Yellow Write-Host " │ 101. NSSM xWin64 (Info) │" -ForegroundColor Yellow Write-Host " │ 101.1. Instalar NSSM │" -ForegroundColor Yellow Write-Host " │ 101.9. Desinstalar NSSM │" -ForegroundColor Yellow Write-Host " │ 102. NGINX-RTMP xWin64 (Info) │" -ForegroundColor Yellow Write-Host " │ 102.1. Instalar NGINX-RTMP │" -ForegroundColor Yellow Write-Host " │ 102.9. Desinstalar NGINX-RTMP │" -ForegroundColor Yellow Write-Host " │ 103. FFmpeg xWin64 (Info) │" -ForegroundColor Yellow Write-Host " │ 103.1. Instalar FFmpeg │" -ForegroundColor Yellow Write-Host " │ 103.2. Listar dispositivos │" -ForegroundColor Yellow Write-Host " │ 103.3. Listar y probar dispositivos │" -ForegroundColor Yellow Write-Host " │ 103.4. Activar dispositivo │" -ForegroundColor Yellow Write-Host " │ 103.9. Desinstalar FFmpeg │" -ForegroundColor Yellow Write-Host " │ │" -ForegroundColor Yellow Write-Host " │───────────────────────────────────────────────│" -ForegroundColor Yellow Write-Host " │ 0. Salir │" -ForegroundColor Yellow Write-Host " └───────────────────────────────────────────────┘" -ForegroundColor DarkGray Write-Host "`n ➜ Elige una opción: " -ForegroundColor Green -NoNewline } # ======================================== # 5. Ejecución principal # ======================================== function Main { do { Show-Menu $option = (Read-Host).Trim() # ✅ CORREGIDO: Paréntesis obligatorios switch ($option) { '0' { Clear-Host Write-Host "`n👋 ¡Hasta luego!`n" -ForegroundColor Green Write-Host "`n`n[Presiona Enter para cerrar la terminal o Ctrl+C para mantener la terminal abierta]" -ForegroundColor DarkGray Read-Host | Out-Null exit 1 } '1' { Clear-Host Write-Host "`n╔════════════════════════════╗" -ForegroundColor Green Write-Host "║ 1. Hello World! ║" -ForegroundColor Green Write-Host "╚════════════════════════════╝`n" -ForegroundColor Green Write-Host " ¡Hola desde PowerShell! 🚀" -ForegroundColor Cyan Write-Host " Ejecutado como Administrador ✅`n" -ForegroundColor Cyan Write-Host "[Presiona Enter para volver al menú]" -ForegroundColor DarkGray Read-Host | Out-Null } '2' { Clear-Host Write-Host "`n╔═══════════════════════════════════════════════╗" -ForegroundColor Magenta Write-Host "║ 2. Información básica del sistema ║" -ForegroundColor Magenta Write-Host "╚═══════════════════════════════════════════════╝`n" -ForegroundColor Magenta $info = Get-SystemInfo foreach ($key in $info.Keys) { if ($info[$key]) { Write-Host " • $($key.PadRight(15)) : $($info[$key])" -ForegroundColor White } } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor DarkGray Read-Host | Out-Null } '3' { Test-SystemPerformance Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor DarkGray Read-Host | Out-Null } '4' { Invoke-Expression "Get-NetAdapter | select interfaceDescription, name, status, linkSpeed" Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor DarkGray Read-Host | Out-Null } '51' { irm https://get.activated.win | iex } '52' { Write-Host "`nConfigurando opliticas" -ForegroundColor Magenta Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser Set-ExecutionPolicy RemoteSigned -Scope CurrentUser Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor DarkGray Read-Host | Out-Null } '101' { Write-Host "`n`n[NSSM (Non-Sucking Service Manager)]" -ForegroundColor White Write-Host "`n Es una herramienta de código abierto para Windows que permite instalar cualquier ejecutable, script o archivo batch como un servicio del sistema, asegurando su ejecución en segundo plano y reiniciándolo automáticamente si falla. Es ideal para mantener aplicaciones activas sin necesidad de que un usuario inicie sesión." -ForegroundColor DarkGray Write-Host "`nCaracterísticas y Funciones Clave:" -ForegroundColor Gray Write-Host "`n Instalación Sencilla: Convierte aplicaciones en servicios de Windows.`n Gestión de Fallos: Monitorea el servicio y lo reinicia si se detiene inesperadamente.`n Interfaz Gráfica y Consola: Permite instalar (nssm install ) y gestionar servicios mediante comandos o una interfaz de usuario.`n Registro de Eventos: Registra la actividad y errores en el visor de eventos de Windows." -ForegroundColor DarkGray Write-Host "`nUso Común:" -ForegroundColor Gray Write-Host "`n Ejecutar aplicaciones en segundo plano automáticamente al iniciar Windows.`n Gestionar servicios que requieren reinicios automáticos (ej. servidores web, agentes de monitoreo)." -ForegroundColor DarkGray Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '101.1' { $nssmPath = "C:\tools\nssm\nssm.exe" $nssmDir = "C:\tools\nssm" $nssmDirLogs = "C:\tools\logs\nssm" # Detener if (Test-Path -Path $nssmDir) { Write-Host "NSSM Ya debe estar instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 # exit 0 } else { # Crear directorio New-Item -ItemType Directory -Path $nssmDirLogs -Force | Out-Null New-Item -ItemType Directory -Path $nssmDir -Force | Out-Null Start-Sleep -Seconds 2 $tempPath = "$env:TEMP\nssm" if (Test-Path -Path $tempPath -PathType Leaf) { Remove-Item -Path "$tempPath" -Force } # Descargar NSSM Write-Host "Descargando NSSM..." Invoke-WebRequest "https://getwin.demedallo.com/archives/nssm-2.24.zip" -OutFile "$env:TEMP\nssm-2.24.zip" # Extraer solo el binario de 64 bits Write-Host "Extrayendo NSSM..." Expand-Archive -Path "$env:TEMP\nssm-2.24.zip" -DestinationPath "$tempPath" Start-Sleep -Seconds 2 $nssmX64TempPath = "$tempPath\nssm-2.24\win64\nssm.exe" if (Test-Path -Path $nssmDir -PathType Leaf) { Remove-Item -Path "$nssmDir" -Force } Start-Sleep -Seconds 2 Write-Host "Instalando NSSM..." Copy-Item "$nssmX64TempPath" "$nssmPath" Write-Host "Eliminando Temporales..." Remove-Item -Path "$tempPath" -Recurse # Start-Sleep -Seconds 3 Write-Host "Creando rutas NSSM..." $oldPath = [Environment]::GetEnvironmentVariable("Path", "Machine") # Write-Host "oldPath: $oldPath" [Environment]::SetEnvironmentVariable("Path", "$oldPath;$nssmDir", "Machine") $env:Path = [System.Environment]::ExpandEnvironmentVariables(([System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User"))) Start-Sleep -Seconds 3 $newPath = [Environment]::GetEnvironmentVariable("Path", "Machine") Write-Host "newPath: $newPath" Start-Sleep -Seconds 3 Write-Host "Finalizado con exito..." Write-Host "Analizando..." nssm version Write-Host "..." Write-Host "Terminado!..." Write-Host "Ejecute el intalador de NGINX!..." Write-Host "" Write-Host "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser" } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '101.9' { $nssmPath = "C:\tools\nssm\nssm.exe" $nssmDir = "C:\tools\nssm" $nssmDirLogs = "C:\tools\logs\nssm" if (Test-Path -Path $nssmDir) { # Eliminar directorio Write-Host "Desinstalando NSSM..." Get-Process | Where-Object { $_.Path -like "$nssmDir*" } | Stop-Process -Force -ErrorAction SilentlyContinue Remove-Item -Path "$nssmDir" -Recurse -Force Start-Sleep -Seconds 3 Write-Host "Eliminando rutas NSSM..." $oldPath = [Environment]::GetEnvironmentVariable("Path", "Machine") $newPath = ($oldPath.Split(';') | Where-Object { $_ -ne $nssmDir }) -join ';' [Environment]::SetEnvironmentVariable("Path", $newPath, "Machine") } else { Write-Host "NSSM no esta instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '102' { Write-Host "`n`n[NGINX-RTMP ()]" -ForegroundColor White Write-Host "`n se refiere al uso del servidor web NGINX de alto rendimiento con un módulo adicional (el módulo nginx-rtmp) para crear un servidor autohospedado potente para la transmisión de video en vivo utilizando el Protocolo de mensajería en tiempo real (RTMP)." -ForegroundColor DarkGray Write-Host "`nAspectos Clave de NGINX-RTMP:" -ForegroundColor Gray Write-Host "`n Funcionalidad: Permite recibir transmisiones RTMP (por ejemplo, desde OBS Studio) y distribuirlas a múltiples espectadores.`n Protocolos: Soporta RTMP para entrada/salida y HLS para reproducción en navegadores web.`n Características: Incluye transcodificación en línea (con FFmpeg), grabación de transmisiones, compatibilidad con múltiples aplicaciones en vivo y módulos de control HTTP.`n Uso: Es ideal para montar servidores de streaming propios, retransmitir a varias plataformas simultáneamente o gestionar contenido multimedia con bajo costo y alto rendimiento.`n Instalación: Generalmente se añade como un módulo extra a NGINX en sistemas Linux." -ForegroundColor DarkGray Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '102.1' { $nginxPath = "C:\tools\nginx\nginx.exe" $nginxDir = "C:\tools\nginx" $nginxDirLogs = "C:\tools\logs\nginx" $nginxDirLogs2 = "C:\tools\nginx\logs" $nginxArguments = '-c ' $nginxArguments += $nginxDir # $nginxArguments += "\conf\nginx.conf -p . -g `"daemon off;`"" $nginxArguments += "\conf\nginx.conf -p . " $nssmPath = "nssm" $serviceName = "nginx-monitor" # Detener if (Test-Path -Path $nginxDir) { Write-Host "NGINX-RTMP Ya debe estar instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 # exit 0 } else { New-Item -ItemType Directory -Path $nginxDirLogs -Force | Out-Null New-Item -ItemType Directory -Path $nginxDirLogs2 -Force | Out-Null # Descargar NGINX-RTMP Write-Host "Descargando NGINX-RTMP..." Invoke-WebRequest "https://getwin.demedallo.com/archives/nginx-rtmp-win64.zip" -OutFile "$env:TEMP\nginx-rtmp-win64.zip" # Extraer solo el binario de 64 bits Expand-Archive -Path "$env:TEMP\nginx-rtmp-win64.zip" -DestinationPath $nginxDir Start-Sleep -Seconds 3 Write-Host "Eliminando Temporales..." Remove-Item "$env:TEMP\nginx-rtmp-win64.zip" Start-Sleep -Seconds 3 # Instalar el servicio CON ARGUMENTOS & $nssmPath install $serviceName $nginxPath $nginxArguments # Configurar parámetros (opcional, pero recomendado) & $nssmPath set $serviceName AppDirectory "$nginxDir" & $nssmPath set $serviceName AppStdout "$nginxDirLogs\stdout.log" & $nssmPath set $serviceName AppStderr "$nginxDirLogs\stderr.log" & $nssmPath set $serviceName AppExit Default Restart # Reinicia si nginx falla & $nssmPath set $serviceName Description "Monitor nginx" # Iniciar el servicio & $nssmPath start $serviceName } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '102.9' { # Ruta a nginx $nssmPath = "nssm" $ffmpegDir = "C:\tools\ffmpeg" if (Test-Path -Path $ffmpegDir) { # Ruta a nginx $nssmPath = "nssm" # Nombre del servicio $serviceName = "nginx-monitor" # Detener el servicio & $nssmPath stop $serviceName # Eliminar el servicio & $nssmPath remove $serviceName confirm # Eliminar directorio Get-Process | Where-Object { $_.Path -like "$ffmpegDir*" } | Stop-Process -Force -ErrorAction SilentlyContinue Remove-Item -Path "$ffmpegDir" -Recurse } else { Write-Host "NGINX-RTMP no esta instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '103' { Write-Host "`n`n[FFmpeg ()]" -ForegroundColor White Write-Host "`n FFmpeg es un framework multimedia de código abierto, líder y gratuito, diseñado para grabar, convertir (transcodificar), transmitir y editar prácticamente cualquier formato de audio y vídeo. Funciona principalmente a través de la línea de comandos, siendo conocido como la `"navaja suiza`" del procesamiento multimedia por su capacidad de manipular archivos de video en una gran variedad de dispositivos." -ForegroundColor DarkGray Write-Host "`nCaracterísticas principales de FFmpeg:" -ForegroundColor Gray Write-Host "`n Códecs y Formatos: Soporta una amplia gama de formatos antiguos, modernos y contenedores de video/audio.`nComponentes Clave: Incluye herramientas esenciales como ffmpeg (conversión), ffprobe (análisis de metadatos) y ffplay (reproductor simple).`nFuncionalidades: Permite decodificar, codificar, transcodificar, multiplexar, demultiplexar, transmitir y filtrar archivos.`nCompatibilidad: Se ejecuta en múltiples sistemas operativos, incluyendo Linux, Mac OS X y Windows.`nBibliotecas: Incluye libavcodec (biblioteca de códecs), libavformat (manejo de contenedores) y libavfilter (filtros de audio/video)." -ForegroundColor DarkGray Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '103.1' { $ffmpegPath = "C:\tools\ffmpeg\ffmpeg.exe" $ffmpegDir = "C:\tools\ffmpeg" $ffmpegDirLogs = "C:\tools\logs\ffmpeg" # Detener if (Test-Path -Path $ffmpegDir) { Write-Host "FFmpeg Ya debe estar instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 # exit 0 } else { # Crear directorio New-Item -ItemType Directory -Path $ffmpegDir -Force | Out-Null New-Item -ItemType Directory -Path $ffmpegDirLogs -Force | Out-Null Start-Sleep -Seconds 2 # Descargar FFmpeg Write-Host "Descargando FFmpeg..." Invoke-WebRequest "https://getwin.demedallo.com/archives/ffmpeg-8.0.1-essentials_build.zip" -OutFile "$env:TEMP\ffmpeg-8.0.1-essentials_build.zip" # Extraer solo el binario de 64 bits Write-Host "Extrayendo FFmpeg..." Expand-Archive -Path "$env:TEMP\ffmpeg-8.0.1-essentials_build.zip" -DestinationPath "$env:TEMP\ffmpeg" Start-Sleep -Seconds 2 Write-Host "Instalando FFmpeg..." Copy-Item "$env:TEMP\ffmpeg\ffmpeg-8.0.1-essentials_build\bin\ffmpeg.exe" C:\tools\ffmpeg\ Copy-Item "$env:TEMP\ffmpeg\ffmpeg-8.0.1-essentials_build\bin\ffplay.exe" C:\tools\ffmpeg\ Copy-Item "$env:TEMP\ffmpeg\ffmpeg-8.0.1-essentials_build\bin\ffprobe.exe" C:\tools\ffmpeg\ Start-Sleep -Seconds 3 Write-Host "Eliminando Temporales..." Remove-Item -Path "$env:TEMP\ffmpeg-8.0.1-essentials_build.zip" -Recurse Remove-Item -Path "$env:TEMP\ffmpeg" -Recurse Write-Host "Creando rutas FFmpeg..." $oldPath = [Environment]::GetEnvironmentVariable("Path", "Machine") [Environment]::SetEnvironmentVariable("Path", "$oldPath;$ffmpegDir", "Machine") Start-Sleep -Seconds 3 $env:Path = [System.Environment]::ExpandEnvironmentVariables(([System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User"))) Start-Sleep -Seconds 3 Write-Host "Finalizado con exito..." Write-Host "..." Write-Host "Analizando..." Write-Host "..." # ffmpeg -list_devices true -f dshow -i dummy # Ejecutar FFmpeg y capturar stderr (donde imprime los dispositivos) $devices = ffmpeg -list_devices true -f dshow -i dummy 2>&1 | Where-Object { $_ -match '^\[dshow.*\]\s+"[^"]+"' } | ForEach-Object { if ($_ -match '"([^"]+)"') { $matches[1] } } # Mostrar cada nombre en un foreach $i = 0 foreach ($device in $devices) { Write-Host $i "." $device $i++ } Write-Host "Terminado!..." Write-Host "Ejecute el lanzador de streaming continuo!..." Write-Host "" Write-Host "⚠️ Si tienes restricciones de ejecución, primero ejecuta:" Write-Host "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser" } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '103.2' { # Ruta a nginx $ffmpegDir = "C:\tools\ffmpeg" if (Test-Path -Path $ffmpegDir) { Write-Host "`n Nota: Si aún ves caracteres extraños, ejecuta primero en PowerShell:`nchcp 1252" -ForegroundColor Red # === Obtener dispositivos === Write-Host "`n[+] Listando dispositivos..." -ForegroundColor Cyan $originalEncoding = [Console]::OutputEncoding [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding(1252) try { $output = ffmpeg -list_devices true -f dshow -i dummy 2>&1 } finally { [Console]::OutputEncoding = $originalEncoding } $devices = @() foreach ($line in $output) { if ($line -match '^\s*\[.*dshow.*\]\s+"([^"]+)"') { $devices += $matches[1] } } $devices += "Captura de Pantalla (desktop)" # === Mostrar menú === if ($devices.Count -eq 0) { Write-Host "`n[!] No se encontraron dispositivos." -ForegroundColor Red exit 1 } Write-Host "`n=== DISPOSITIVOS ===" -ForegroundColor Green for ($i = 0; $i -lt $devices.Count; $i++) { Write-Host " $($i+1). $($devices[$i])" -ForegroundColor White } } else { Write-Host "FFmpeg no esta instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '103.3' { # Ruta a nginx $ffmpegDir = "C:\tools\ffmpeg" if (Test-Path -Path $ffmpegDir) { Write-Host "`n Nota: Si aún ves caracteres extraños, ejecuta primero en PowerShell:`nchcp 1252" -ForegroundColor Red $RTMP_BASE = "rtmp://localhost/live/" $FRAMERATE = 25 # Reducido de 10 → 15 (mejor fluidez sin saturar) $BITRATE = "2000k" # Aumentado ligeramente para mejor calidad $PRESET = "veryfast" # ultrafast, veryfast, faster $BUFFERSET = "100M" $VIDEO_SIZE = "" # Vacío = resolución nativa del dispositivo $TUNE = "zerolatency" # Optimizado para streaming sin perder calidad function Sanitize-StreamKey { param([string]$name) return ($name -replace '[^a-zA-Z0-9]', '_').Trim('_').ToLower() } # === Obtener dispositivos === Write-Host "`n[+] Listando dispositivos..." -ForegroundColor Cyan $originalEncoding = [Console]::OutputEncoding [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding(1252) try { $output = ffmpeg -list_devices true -f dshow -i dummy 2>&1 } finally { [Console]::OutputEncoding = $originalEncoding } $devices = @() foreach ($line in $output) { if ($line -match '^\s*\[.*dshow.*\]\s+"([^"]+)"') { $devices += $matches[1] } } $devices += "Captura de Pantalla (desktop)" # === Mostrar menú === if ($devices.Count -eq 0) { Write-Host "`n[!] No se encontraron dispositivos." -ForegroundColor Red exit 1 } Write-Host "`n=== DISPOSITIVOS ===" -ForegroundColor Green for ($i = 0; $i -lt $devices.Count; $i++) { Write-Host " $($i+1). $($devices[$i])" -ForegroundColor White } Write-Host "`n 0. Salir" -ForegroundColor Gray # === Seleccionar === do { $selection = Read-Host "`nSelecciona (0-$($devices.Count))" $numSel = 0 $isValid = [int]::TryParse($selection, [ref]$numSel) -and $numSel -ge 0 -and $numSel -le $devices.Count if (-not $isValid) { Write-Host " [!] Inválido." -ForegroundColor Red } } while (-not $isValid) if ($numSel -eq 0) { exit 0 } $selectedDevice = $devices[$numSel - 1] Write-Host "`n[+] Seleccionado: $selectedDevice" -ForegroundColor Cyan # === Transmitir === if ($selectedDevice -like "*Captura de Pantalla*") { $streamKey = "desktop" # Captura de pantalla: menos sensible a buffers $cmd = "ffmpeg -hide_banner -loglevel error -nostats -f gdigrab -framerate 10 -i desktop -c:v libx264 -pix_fmt yuv420p -preset $PRESET -b:v 1000k -f flv `"$RTMP_BASE$streamKey`"" } else { $streamKey = Sanitize-StreamKey $selectedDevice $sizeParam = if ($VIDEO_SIZE) { "-video_size $VIDEO_SIZE" } else { "" } # ⭐ PARÁMETROS CLAVE para evitar buffer overflow: $cmd = "ffmpeg -hide_banner -loglevel error -nostats -f dshow -rtbufsize $BUFFERSET -fflags nobuffer -flags low_delay $sizeParam -i `"video=$selectedDevice`" -c:v libx264 -pix_fmt yuv420p -preset $PRESET -tune $TUNE -b:v $BITRATE -g 60 -f flv `"$RTMP_BASE$streamKey`"" } Write-Host "`n[+] Transmitiendo '$selectedDevice' -> $RTMP_BASE$streamKey" -ForegroundColor Magenta Write-Host " Calidad: $BITRATE @ $FRAMERATE fps | Preset: $PRESET | Buffer: $BUFFERSET" -ForegroundColor Cyan Write-Host "`n Comando: $cmd" -ForegroundColor Green Write-Host "`nIniciando... (presiona 'q' para detener)`n" -ForegroundColor Yellow Invoke-Expression $cmd Write-Host "`n[!] Transmisión finalizada." -ForegroundColor Yellow } else { Write-Host "FFmpeg no esta instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '103.4' { # Ruta a nginx $ffmpegPath = "C:\tools\ffmpeg\ffmpeg.exe" $ffmpegDir = "C:\tools\ffmpeg" if (Test-Path -Path $ffmpegDir) { Write-Host "`n Nota: Si aún ves caracteres extraños, ejecuta primero en PowerShell:`nchcp 1252" -ForegroundColor Red $RTMP_BASE = "rtmp://localhost/live/" $FRAMERATE = 25 # Reducido de 10 → 15 (mejor fluidez sin saturar) $BITRATE = "2000k" # Aumentado ligeramente para mejor calidad $PRESET = "veryfast" # ultrafast, veryfast, faster $BUFFERSET = "100M" $VIDEO_SIZE = "" # Vacío = resolución nativa del dispositivo $TUNE = "zerolatency" # Optimizado para streaming sin perder calidad function Sanitize-StreamKey { param([string]$name) return ($name -replace '[^a-zA-Z0-9]', '_').Trim('_').ToLower() } # === Obtener dispositivos === Write-Host "`n[+] Listando dispositivos..." -ForegroundColor Cyan $originalEncoding = [Console]::OutputEncoding [Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding(1252) try { $output = ffmpeg -list_devices true -f dshow -i dummy 2>&1 } finally { [Console]::OutputEncoding = $originalEncoding } $devices = @() foreach ($line in $output) { if ($line -match '^\s*\[.*dshow.*\]\s+"([^"]+)"') { $devices += $matches[1] } } $devices += "Captura de Pantalla (desktop)" # === Mostrar menú === if ($devices.Count -eq 0) { Write-Host "`n[!] No se encontraron dispositivos." -ForegroundColor Red exit 1 } Write-Host "`n=== DISPOSITIVOS ===" -ForegroundColor Green for ($i = 0; $i -lt $devices.Count; $i++) { Write-Host " $($i+1). $($devices[$i])" -ForegroundColor White } Write-Host "`n 0. Salir" -ForegroundColor Gray # === Seleccionar === do { $selection = Read-Host "`nSelecciona (0-$($devices.Count))" $numSel = 0 $isValid = [int]::TryParse($selection, [ref]$numSel) -and $numSel -ge 0 -and $numSel -le $devices.Count if (-not $isValid) { Write-Host " [!] Inválido." -ForegroundColor Red } } while (-not $isValid) if ($numSel -eq 0) { exit 0 } $selectedDevice = $devices[$numSel - 1] Write-Host "`n[+] Seleccionado: $selectedDevice" -ForegroundColor Cyan # === Transmitir === if ($selectedDevice -like "*Captura de Pantalla*") { $streamKey = "desktop" # Captura de pantalla: menos sensible a buffers $cmd = "-hide_banner -loglevel error -nostats -f gdigrab -framerate $FRAMERATE -i desktop -c:v libx264 -pix_fmt yuv420p -preset $PRESET -b:v $BITRATE -f flv `"$RTMP_BASE$streamKey`"" } else { $streamKey = Sanitize-StreamKey $selectedDevice $sizeParam = if ($VIDEO_SIZE) { "-video_size $VIDEO_SIZE" } else { "" } # ⭐ PARÁMETROS CLAVE para evitar buffer overflow: $cmd = "-hide_banner -loglevel error -nostats -f dshow -rtbufsize $BUFFERSET -fflags nobuffer -flags low_delay $sizeParam -i `"video=$selectedDevice`" -c:v libx264 -pix_fmt yuv420p -preset $PRESET -tune $TUNE -b:v $BITRATE -g 60 -f flv `"$RTMP_BASE$streamKey`"" } Write-Host "`n[+] Transmitiendo '$selectedDevice' -> $RTMP_BASE$streamKey" -ForegroundColor Magenta Write-Host " Calidad: $BITRATE @ $FRAMERATE fps | Preset: $PRESET | Buffer: $BUFFERSET" -ForegroundColor Cyan Write-Host "`n Comando: $cmd" -ForegroundColor Green # Crear script de transmisión $taskName = "FFmpeg rtmp $streamKey" $scriptPath = "C:\tools\stream" $streamScript = @" `$logFile = `"$scriptPath\logs\$streamKey.log`" while (`$true) { try { Start-Process -FilePath `"$ffmpegPath`" -Argument '$cmd' -WindowStyle Hidden -Wait } catch { Start-Sleep -Seconds 5 } Start-Sleep -Seconds 2 } "@ if (Test-Path -Path $scriptPath) {} else { New-Item -ItemType Directory -Path $scriptPath -Force | Out-Null Start-Sleep -Seconds 2 } Set-Content -Path "$scriptPath\$streamKey.ps1" -Value $streamScript -Encoding UTF8 # Crear tarea programada moderna $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -ExecutionPolicy Bypass -File `"$scriptPath\$streamKey.ps1`"" $trigger = New-ScheduledTaskTrigger -AtLogOn # $principal = New-ScheduledTaskPrincipal -UserId "$env:USERNAME" -RunLevel Limited # $principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -RunLevel Highest $principal = New-ScheduledTaskPrincipal -UserId "$env:USERNAME" -RunLevel Highest # $principal = New-ScheduledTaskPrincipal -UserId "S-1-5-18" -LogonType ServiceAccount -RunLevel Highest $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) # Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Servicio de actualización de visualización del sistema" -Force | Out-Null Register-ScheduledTask -TaskName "$taskName" -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Servicio de actualización de visualización del sistema" -Force | Out-Null # Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "$taskName" -User "NT AUTHORITY\SYSTEM" -RunLevel Highest -Description "Servicio de actualización de visualización del sistema" -Force | Out-Null Write-Host "✅ Instalación completada en Windows 11." Write-Host "La transmisión comenzará al próximo inicio de sesión." Set-ExecutionPolicy Bypass -Scope CurrentUser -Force # Write-Host "`nIniciando... (presiona 'q' para detener)`n" -ForegroundColor Yellow # Invoke-Expression $cmd # Write-Host "`n[!] Transmisión finalizada." -ForegroundColor Yellow } else { Write-Host "FFmpeg no esta instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } '103.9' { # Ruta a nginx $nssmPath = "nssm" $ffmpegDir = "C:\tools\ffmpeg" if (Test-Path -Path $ffmpegDir) { # Eliminar directorio Write-Host "Desinstalando FFmpeg..." Get-Process | Where-Object { $_.Path -like "$ffmpegDir*" } | Stop-Process -Force -ErrorAction SilentlyContinue # Eliminar directorio Write-Host "Desinstalando FFmpeg..." Remove-Item -Path $ffmpegDir -Recurse Start-Sleep -Seconds 3 Write-Host "Eliminando rutas FFmpeg..." $oldPath = [Environment]::GetEnvironmentVariable("Path", "Machine") $newPath = ($oldPath.Split(';') | Where-Object { $_ -ne $ffmpegDir }) -join ';' [Environment]::SetEnvironmentVariable("Path", $newPath, "Machine") } else { Write-Host "FFmpeg no esta instalado..." -ForegroundColor Red Start-Sleep -Seconds 1.5 } Write-Host "`n`n[Presiona Enter para volver al menú]" -ForegroundColor Green Read-Host | Out-Null } default { if ($option -ne '') { Write-Host "`n⚠️ Opción inválida. Selecciona 0, 1, 2, 3 o 4." -ForegroundColor Red Start-Sleep -Seconds 1.5 } } } } while ($true) } # ======================================== # 6. Punto de entrada # ======================================== Write-Host "`n🚀 Iniciando herramientas del sistema..." -ForegroundColor Cyan Start-Sleep -Milliseconds 500 Main