Stream music using youtube-dl and ffplay

Started by ron77_db, Apr 01, 2022, 08:27 AM

Previous topic - Next topic

ron77_db

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)

ron77

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)