6
\$\begingroup\$

My question is in regards to combining youtube-dl, ffmpeg, ffplay and PowerShell to handle video URLs.

Some examples I've seen have piped a binary stream from youtube-dl to an external player using the Windows Command Prompt as demonstrated:

youtube-dl --output - "https://youtube.com/mygroovycontent" | mpc-hc.exe /play /close -

This works fine in Command Prompt as it does not mangle the binary stream. If you try and run the same command in PowerShell it doesn't handle the binary stream so well and modifies the output, making it unreadable to the external player.

In light of this I've written the following PowerShell function to get around this issue. It tries to mirror a similar function I've written in Bash (see this).

The reason I've handled youtube-dl, ffmpeg and ffplay separately is that defining the ffmpeg binary location in youtube-dl as an external program creates some issues when passing it in PowerShell.

I was hoping that someone could take a look at my script and provide some feedback on what I have done here and if it can be improved upon or if a better implementation is already available.

Function streamer
{

Param
(
[string] $streamURL
)

Begin
{
}

Process
{
$streamDir = "$env:TEMP\YTD.d"

$ytdBin = "Z:\PortableApps\CommandLineApps\youtube-dl\youtube-dl.exe"
$streamExtractor = &$ytdBin --no-warnings --get-url $streamURL

$ffmpegBin = "Z:\PortableApps\CommandLineApps\ffmpeg-20170702-c885356-win64-static\bin\ffmpeg.exe"
$ffplayBin = "Z:\PortableApps\CommandLineApps\ffmpeg-20170702-c885356-win64-static\bin\ffplay.exe"

if 
(
-not (Test-Path -Path $streamDir -PathType Any)
)

{
New-Item $streamDir -type directory -ErrorAction SilentlyContinue
}

Start-Process -FilePath $ffmpegBin -ArgumentList "-loglevel quiet -i $streamExtractor -c copy $streamDir\streamContainer.m2ts" -NoNewWindow -ErrorAction SilentlyContinue

Do
{
Start-Sleep -Seconds 1
} 

Until 
(
(Get-Item $streamDir\streamContainer.m2ts -ErrorAction SilentlyContinue).Length -gt 256kb
)

&$ffplayBin -loglevel quiet $streamDir\streamContainer.m2ts

if 
(
(Test-Path -Path $streamDir -PathType Any) -eq $true -and (Get-Process -Name ffplay -ErrorAction SilentlyContinue) -eq $null
) 

{

Do
{
Stop-Process -Name ffmpeg -ErrorAction SilentlyContinue
}

Until
(
(Get-Process -Name ffmpeg -ErrorAction SilentlyContinue) -eq $null
)

Remove-Item $streamDir -Recurse -ErrorAction SilentlyContinue
}
}

End
{
}

}

streamer -streamURL https://www.youtube.com/watch?v=9uFXw7vKz14
\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to Code Review. Are you morally opposed to indentation or was it too challenging to paste into a question on here? \$\endgroup\$ – chicks Jul 11 '17 at 13:33
  • \$\begingroup\$ FWIW, I'd simply use mpchc's sibling with built-in youtube support: MPC-BE. \$\endgroup\$ – wOxxOm Jul 11 '17 at 19:35
  • \$\begingroup\$ @chicks Thanks for the feedback. <justsomething.co/wp-content/uploads/2016/04/…> Yes, but can MPC-BE do general extraction though? For example if I input this URL: <nautiluslive.org> Will it start playing Channel1? I find that youtube-dl can also handle non-youtube streams well. \$\endgroup\$ – Adam Chilcott Jul 11 '17 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.