RetroCoders Community

FreeBasic Programming => FreeBasic Tips & Tricks => Topic started by: ron77_db on Apr 01, 2022, 08:27 AM

Title: Stream music using youtube-dl and ffplay
Post by: ron77_db on Apr 01, 2022, 08:27 AM
hello...

this code will give you the ability to stream music and sound from youtube and SoundCloud or any other media content (just the sound or music) it depends only on youtube-dl to find the URL of the sound/music and to stream it using ffplay (part of ffmpeg)
you need both of them installed on your machine and set into system PATH... works for both windows (compile with 32 bit fbc) or linux (compile with 64 bit fbc)

#include once "crt.bi"
 
#ifdef __FB_WIN32__
  #include once "windows.bi"
  function _InternalPlay( sUrl as string ) as uinteger
    dim as STARTUPINFO tInfo = type(sizeof(STARTUPINFO))
    dim as PROCESS_INFORMATION tProc 
    var sPlay = "ffplay -nodisp -i -loglevel error """+sUrl+""""
    if CreateProcess(null,sPlay,null,null,true,CREATE_NEW_PROCESS_GROUP,null,null,@tInfo,@tProc) = 0 then
      return 0
    end if
    CloseHandle(tProc.hProcess) : CloseHandle(tProc.hThread)
    return tProc.dwProcessId       
  end function 
  sub StopAudioUrl( uAudioUrl as uinteger )
    if uAudioUrl = 0 then exit sub
    GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT , uAudioUrl )
  end sub
#else
  #include once "crt/unistd.bi"
  #include once "crt/sys/types.bi" 
  function _InternalPlay( sUrl as string ) as uinteger
    var child_pid = fork()
    select case child_pid
    case -1: return 0
    case  0: execlp("ffplay","ffplay","-nodisp","-loglevel","error","-i",sUrl,cptr(any ptr,0))
    end select
    return child_pid   
  end function   
  declare function _killpid cdecl alias "kill" (pid as pid_t, sig as uinteger) as uinteger 
  sub StopAudioUrl( uAudioUrl as uinteger )
    #ifndef SIGINT
      const SIGINT = 2 , SIGTERM = 15   
    #endif
    _killpid(uAudioUrl,SIGINT)
  end sub
#endif
 
function PlayAudioUrl( sUrl as string ) as uinteger
  var f = freefile(), sDirectUrl = "" , sTemp = ""
  #ifdef __FB_WIN32__
  const sDevNul = "nul"
  #else
  const sDevNul = "/dev/null"
  #endif 
  var sCom = "youtube-dl -f worstaudio -g "+sUrl+" 2>"+sDevNul
  open pipe sCom for input as #f
  while not eof(f)
    line input #f, sTemp
    if lcase(left(sTemp,8))="https://" then sDirectUrl = sTemp
  wend
  close #f
  if len(sDirectUrl)=0 then return 0 
  return _InternalPlay( "async:"+sDirectUrl )
end function
#undef _InternalPlay
 
'var uMusic = PlayAudioUrl( "https://www.youtube.com/watch?v=sjkrrmBnpGE" )
'sleep : stopAudioUrl(uMusic)
Title: Re: Stream music using youtube-dl and ffplay
Post by: ron77 on Jun 14, 2022, 07:55 AM
okay here is same code but one that works for sure on windows :/

#include once "crt.bi"
 
#ifdef __FB_WIN32__
  #include once "windows.bi"
  function _InternalPlay( sUrl as string ) as uinteger
    dim as STARTUPINFO tInfo = type(sizeof(STARTUPINFO))
    dim as PROCESS_INFORMATION tProc 
    var sPlay = "ffplay -nodisp -i -loglevel error """+sUrl+""""
    if CreateProcess(null,sPlay,null,null,true,CREATE_NEW_PROCESS_GROUP,null,null,@tInfo,@tProc) = 0 then
      return 0
    end if
    CloseHandle(tProc.hProcess) : CloseHandle(tProc.hThread)
    return tProc.dwProcessId       
  end function 
  sub StopAudioUrl( uAudioUrl as uinteger )
    if uAudioUrl = 0 then exit sub
    GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT , uAudioUrl )
  end sub
#else
  #include once "crt/unistd.bi"
  #include once "crt/sys/types.bi" 
  function _InternalPlay( sUrl as string ) as uinteger
    var child_pid = fork()
    select case child_pid
    case -1: return 0
    case  0: execlp("ffplay","ffplay","-nodisp","-loglevel","error","-i",sUrl,cptr(any ptr,0))
    end select
    return child_pid   
  end function   
  declare function _killpid cdecl alias "kill" (pid as pid_t, sig as uinteger) as uinteger 
  sub StopAudioUrl( uAudioUrl as uinteger )
    #ifndef SIGINT
      const SIGINT = 2 , SIGTERM = 15   
    #endif
    _killpid(uAudioUrl,SIGINT)
  end sub
#endif
 
function PlayAudioUrl( sUrl as string ) as uinteger
  var f = freefile(), sDirectUrl = "" , sTemp = ""
  #ifdef __FB_WIN32__
  const sDevNul = "nul"
  #else
  const sDevNul = "/dev/null"
  #endif 
  var sCom = "youtube-dl -f worstaudio -g "+sUrl+" 2>"+sDevNul
  open pipe sCom for input as #f
  while not eof(f)
    line input #f, sTemp
    if lcase(left(sTemp,8))="https://" then sDirectUrl = sTemp
  wend
  close #f
  if len(sDirectUrl)=0 then return 0
  #ifdef __fb_win32__
return _InternalPlay( sDirectUrl )
  #else
return _InternalPlay( "async: "+sDirectUrl )
  #endif
end function
#undef _InternalPlay
 
var uMusic = PlayAudioUrl( "https://www.youtube.com/watch?v=AkPcNCnQU70" )
sleep : stopAudioUrl(uMusic)