Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Foobar Youtube Radio (Read 57458 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Foobar Youtube Radio

Reply #100
omgg work so good i love u ill change that skinn. you got any skin?


You can find great skins on deviantart.com , i was used this from few posts above, it's skin from falstaff(br3tt), but now im use DUI foobar, here is my config:


Foobar Youtube Radio

Reply #101
Youtube Radio, new version:  Link>>

Due to changes in foo_youtube component, ''love'', ''unlove video'' not working anymore. Now fixed..


Foobar Youtube Radio

Reply #102
I really like this component
Now I can listen to Youtube directly on FOOBAR2000

Dear Mire777
How can I add my own last.fm radio station on FOOBAR???
Or add some other last.fm radio station on this plugin???

Thank you very much for your help!!!

Foobar Youtube Radio

Reply #103
I really like this component
Now I can listen to Youtube directly on FOOBAR2000

Dear Mire777
How can I add my own last.fm radio station on FOOBAR???
Or add some other last.fm radio station on this plugin???

Thank you very much for your help!!!


With my script, you can play:

-artist radio
-genre radio
-top tracks from chosen artist
-similar artist track
-Loved tracks [(don't work with last.fm)]

If this is what you need, download script from here: Link>>
You have instructions on site..

In short:

First install WSH plugin 1.5.6. : WSH 1.5.6
Then download 'zip' file: Foobar Youtube Radio.zip

Put 'buttons-yt' folder in foobar profile folder.
After that open new wsh panel and paste script from: 'YT.txt'

Foobar Youtube Radio

Reply #104
Script was updated, link>
-Now using last.fm API.
-Fixed small bugs..

Foobar Youtube Radio

Reply #105
Script was updated, link>
-Now using last.fm API.
-Fixed small bugs..


I've got this error message.

WSH Panel Mod (Youtube Radio by Mire777): Microsoft JScript Runtime Error:
Procedure call or argument is not valid
File: <main>
Line: 214, Col: 2
<source text only available at compile time>

I'm using WSH Panel Mod 1.5.11 due to the other scripts for my foobar.
Is there any simple method to fix this error without downgrading WSH Panel Mod?

Foobar Youtube Radio

Reply #106
I've got this error message.

WSH Panel Mod (Youtube Radio by Mire777): Microsoft JScript Runtime Error:
Procedure call or argument is not valid
File: <main>
Line: 214, Col: 2
<source text only available at compile time>

I'm using WSH Panel Mod 1.5.11 due to the other scripts for my foobar.
Is there any simple method to fix this error without downgrading WSH Panel Mod?

I haven't converted AppendMenuItem() to the new AppendTo() method, because i have some scripts that need to work in older WSH, changing this is not really necessary, as the old method continues to work in WSH 1.5.6.

As people now use Marc WSH 1.5.10-11, i will convert this in next release.
Here is modified script for you and others who use WSH 1.5.10-11:

''shift>left click>configure'' , replace script with this:

Code: [Select]
// ==PREPROCESSOR==
// @name "Youtube Radio"
// @author "Mire777"
// @feature "v1.4"
// @feature "watch-metadb"
// ==/PREPROCESSOR==

//Properties
//Api(1):d9f567e4a618a37dac934274e14b82b0
//Api(2):f21088bf9097b49ad4e7f487abab981e
API = window.GetProperty("Last.fm Api", "f21088bf9097b49ad4e7f487abab981e");
YT_PLS_FOCUS = window.GetProperty("YT  Playlist", "0");
YT_AUTO = window.GetProperty("YT  Auto", "0");
YT_TRACK = window.GetProperty("YT Track", "");
YT_STATION = window.GetProperty("YT  Station", "");
YT_SIM_ART = window.GetProperty("YT Similar", "");
YT_URL = window.GetProperty("YT URL", "");
art_hot = window.GetProperty("YT  Artist Hotness (1-250)", "250");
gnr_hot = window.GetProperty("YT  Genre Hotness (1-500)", "250")
sng_hot = window.GetProperty("YT  Song Hotness  (1-500)", "100");
yt_pls = window.GetProperty("Playlist", "YT Radio");

//Folder(loved)
fso = new ActiveXObject("Scripting.FileSystemObject");
folder_loved = fb.ProfilePath + "yt_playlists";

var MF_GRAYED = 0x00000001;
var MF_STRING = 0x00000000;
var IDC_ARROW = 32512;
var IDC_HAND = 32649;

function RGB(r, g, b) {
return (0xff000000 | (r << 16) | (g << 8) | (b));
}

function RGBA(r, g, b, a) {
return ((a << 24) | (r << 16) | (g << 8) | (b));
}

function on_colors_changed() {
p.colors_changed();
}

function on_selection_changed() {
p.item_focus_change();
}

function on_playlist_switch() {
set_focus0(); //Check Playlist
}

function on_playback_new_track() {
p.item_focus_change();
}

function on_playback_starting() {
p.item_focus_change();
//Check Playlist Loved
var PLOVED = GetPlaylistID0(yt_pls + " [Loved]");
if (fb.ActivePlaylist == PLOVED) {LOVED();} else
p.item_focus_change();
{LOAD_SIMILAR();}
}

function on_playback_dynamic_info_track() {
p.item_focus_change();
}

function on_playback_stop() {
p.item_focus_change();
}

function on_item_focus_change() {
p.item_focus_change();
}

function on_mouse_leave() {
}

function on_mouse_rbtn_up(x, y) {
p.rbtn_up(x, y);
return true;
}

//Remove False String From File Names
this.clean_filename = function(filename) {
return filename.replace(/[\/\\|:]/g, '-').replace(/\*/g, 'x').replace(/"/g, "''").replace(/[?<>]/g, '_');
}

//Playlist
function GetPlaylistID(Playlist_Name)
{
for (var i = 0; i < fb.PlaylistCount; i++)
{
if (fb.GetPlaylistName(i) == Playlist_Name)
{
return i;
}
}

//Create Playlist If It Doesn't Exist
fb.CreatePlaylist(fb.PlaylistCount, Playlist_Name);
return i;
}

//Playlist(Check)
function GetPlaylistID0(Playlist_Name)
{
for (var i = 0; i < fb.PlaylistCount; i++)
if (fb.GetPlaylistName(i) == Playlist_Name)
{
return i;
}
}

//Focus On Playlist(Check)
function set_focus0()

if (yt_pls>"")
{
var PL_NM = (GetPlaylistID0(yt_pls + " ["+ YT_STATION +"]"));
if (fb.ActivePlaylist == PL_NM) {YT_PLS_FOCUS = 1; window.SetProperty("YT  Playlist", "1");}
else
{YT_PLS_FOCUS = 0; window.SetProperty("YT  Playlist", "0");}
}
}

//Focus On Playlist(YT Radio)
function set_focus()

if (yt_pls>"")
fb.ActivePlaylist = (GetPlaylistID(yt_pls + " ["+ YT_STATION +"]"));
}

//Focus On Playlist(Same Video)
function set_focus2()

if (yt_pls>"")
fb.ActivePlaylist = (GetPlaylistID(yt_pls + " [Same Video]"));
}

//Focus On Playlist(Search Videos)
function set_focus3()

if (yt_pls>"")
fb.ActivePlaylist = (GetPlaylistID(yt_pls + " [Search Videos]"));
}

//Focus On Playlist(Top Tracks)
function set_focus4()

if (yt_pls>"")
fb.ActivePlaylist = (GetPlaylistID(yt_pls + " [Tracks: "+ p.artist +"]"));
}

//Focus On Playlist(Loved)
function set_focus6()
{
if (yt_pls>"")
fb.ActivePlaylist = (GetPlaylistID(yt_pls + " [Loved]"));
}

//Panel
    function panel(name, features) {
    this.item_focus_change = function() {
    if (!this.metadb_func) return;
    switch(this.selection_mode) {
    case 0:
    this.metadb = fb.GetSelection();
    break;
    case 1:
    this.metadb = fb.IsPlaying ? fb.GetNowPlaying() : fb.GetFocusItem();
    break;
    case 2:
    this.metadb = fb.GetFocusItem();
    break;
}
if (this.metadb) on_metadb_changed();
}

//Metadb
this.metadb = fb.IsPlaying ? fb.GetNowPlaying() : fb.GetFocusItem();

//Size
    this.size = function() {
    this.w = window.Width;
    this.h = window.Height;
}

//Move
    this.move = function(x, y) {
    this.mx = x;
    this.my = y;
}

//Menu
    this.rbtn_up = function(x, y) {
    var _menu = window.CreatePopupMenu();
    var q = window.CreatePopupMenu();
    var MF_POPUP = 0x00000010;
    var idx;
    switch(true) {
            case typeof th == "object":
            case typeof im == "object":

on_item_focus_change()           
if (yt_pls>"")
{
if(YT_AUTO==1) _menu.AppendMenuItem(MF_STRING, 9, "Youtube Radio");
if(YT_AUTO==0) _menu.AppendMenuItem(MF_STRING, 10, "Youtube Radio");
_menu.CheckMenuItem(9, YT_AUTO?1:0);

_menu.AppendMenuSeparator();

//POPUP BUTTON
{q.AppendTo(_menu, MF_STRING, "Open");}

//START *POP-UP*
p.artist = p.eval("%artist%");
if (p.artist == "" || p.artist == "?") {q.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "Radio Station by [%artist%]");}
else
{q.AppendMenuItem(MF_STRING, 12, "Radio Station by [" + p.artist.replace(/&/g,"&&") + "]");}

p.artist = p.eval("%artist%");
if (p.artist == "" || p.artist == "?") {q.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "Top Tracks by " + "[%artist%]");}
else
{q.AppendMenuItem(MF_STRING, 14, "Top Tracks by [" + p.artist.replace(/&/g,"&&") + "]");}
//END *POP-UP*

_menu.AppendMenuSeparator();

{
if(YT_PLS_FOCUS==1 && YT_AUTO==1 && YT_STATION>"") {_menu.AppendMenuItem(MF_STRING, 3, "Get Next Video");}
else
{_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "Get Next Video");}

_menu.AppendMenuSeparator();

_menu.AppendMenuItem(MF_STRING, 11, "Start Radio Station");

_menu.AppendMenuSeparator();

//START *LOVED*
//Eval
p.path = p.eval("%path%");
p.artist = p.eval("%artist%");
p.title = p.eval("%title%");

//Filename
filename = folder_loved + "\\"+ clean_filename(p.artist + " - " + p.title) + ".m3u";

//Check Files
var arr = utils.Glob(folder_loved + "\\*.*").toArray();
var a = [];
for (i = 0; i < arr.length; i++) {
if (arr[i]) a.push(arr[i]); 
}

var PLOVED = (GetPlaylistID0(yt_pls + " [Loved]")); //Check Playlist Loved

if (p.path.indexOf("youtube.com")>0 && fb.ActivePlaylist == PLOVED)
{
if (fso.FileExists(filename)) {_menu.AppendMenuItem(MF_STRING, 6, "♥ Un-Love");} else {_menu.AppendMenuItem(MF_STRING, 7, "♥ Love Video");}
if (arr=="" || arr=="?") {_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "♪ Play Loved..");}
else
if (arr>"" || arr>"?") {_menu.AppendMenuItem(MF_STRING, 8, "♪ Next Loved..");}
}

else

if (p.path.indexOf("youtube.com")>0)
{
if (fso.FileExists(filename)) {_menu.AppendMenuItem(MF_STRING, 6, "♥ Un-Love");} else {_menu.AppendMenuItem(MF_STRING, 7, "♥ Love Video");}
if (arr=="" || arr=="?") {_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "♪ Play Loved..");}
if (arr>"" || arr>"?") {_menu.AppendMenuItem(MF_STRING, 8, "♪ Play Loved..");}
}

else

{
{_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "♥ Love Video");}
if (arr=="" || arr=="?") {_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "♪ Play Loved..");}
if (arr>"" || arr>"?") {_menu.AppendMenuItem(MF_STRING, 8, "♪ Play Loved..");}
}
//END *LOVED*

_menu.AppendMenuSeparator();

p.artist = p.eval("%artist%");
if (p.artist == "" || p.artist == "?") {_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "Open Same Video..");}
else
{_menu.AppendMenuItem(MF_STRING, 5, "Open Same Video..");}

/*//Find In Browser
_menu.AppendMenuSeparator();
p.artist = p.eval("%artist%");
if (p.artist == "" || p.artist == "?") {_menu.AppendMenuItem(MF_STRING| MF_GRAYED, 2000, "Find in Browser");}
else
{_menu.AppendMenuItem(MF_STRING, 16, "Find in Browser");}
_menu.AppendMenuSeparator();*/

_menu.AppendMenuItem(MF_STRING, 4, "Search For Videos...");

_menu.AppendMenuSeparator();

_menu.AppendMenuItem(MF_STRING, 1, "Properties...");
}}}

if (yt_pls=="") {_menu.AppendMenuItem(MF_STRING, 1, "Please Set: (FB Playlist)");}
if (utils.IsKeyPressed(0x10)) _menu.AppendMenuItem(MF_STRING, 2, "Configure...");

        idx = _menu.TrackPopupMenu(x, y);
        switch(idx) {
         
          case 1:
window.ShowProperties();
break;
               
          case 2:
window.ShowConfigure();
break;
               
          case 3:
                set_focus(); //Focus On Playlist
LOAD_SIMILAR();
break;
               
          case 4:
                set_focus3(); //Focus on playlist
fb.RunMainMenuCommand("View/Youtube Search");
break;
               
          case 5:
                this.metadb = fb.IsPlaying ? fb.GetNowPlaying() : fb.GetFocusItem();
                set_focus2(); //Focus On Playlist
                LOAD_SAME();
break;
           
          case 6:
                filename = folder_loved + "\\"+ clean_filename(p.artist + " - " + p.title) + ".m3u";
                //Delete File
                if (fso.FileExists(filename)) fso.DeleteFile(filename);
                break;
               
          case 7:
                this.metadb = fb.IsPlaying ? fb.GetNowPlaying() : fb.GetFocusItem();
                p.path = p.eval("%path%");
                p.artist = p.eval("%artist%");
                p.title = p.eval("%title%");
               
                //Create File & Folder
                filename = folder_loved + "\\"+ clean_filename(p.artist + " - " + p.title) + ".m3u";
                if(!fso.FolderExists(folder_loved)) fso.CreateFolder(folder_loved);
               
                //Save File
                function save_file(x) {
                try {
                g_text = "3dydfy://" + p.path;
                ts = fso.OpenTextFile(filename, 2, true, -2);
                ts.Write(g_text);
                ts.close();
                } catch(e) {
                fb.trace("Error saving text: " + e);
                }}
                save_file(filename);
break;

          case 8:
                LOVED();
break;
               
          case 9:
                YT_AUTO = 0;
                window.SetProperty("YT  Auto", "0");
                break;
     
          case 10:
                YT_AUTO = 1;
                window.SetProperty("YT  Auto", "1");
                break;
         
          case 11:
                var Start;
                Start = this.InputBox("Type Artist to Start Station\n\n( *genre - will play genre station)", "Youtube Radio", "");
                if (Start=="")
                {
                }
                else
                {
                YT_PLS_FOCUS = 1;
                window.SetProperty("YT  Playlist", "1");
                YT_AUTO = "1"
                window.SetProperty("YT  Auto", "1");
                YT_STATION = Start;
                window.SetProperty("YT  Station", Start);
                set_focus(); //Focus on playlist
                LOAD_SIMILAR();
                }
                break;
           
          case 12:
                this.metadb = fb.IsPlaying ? fb.GetNowPlaying() : fb.GetFocusItem();
                p.artist = p.eval("%artist%");
                if (p.artist == "" || p.artist == "?") return;
                YT_STATION = p.artist;
                window.SetProperty("YT  Station", p.artist);
                YT_PLS_FOCUS = 1;
                window.SetProperty("YT  Playlist", "1");
                YT_AUTO = "1"
                window.SetProperty("YT  Auto", "1");
                set_focus(); //Focus On Playlist
                LOAD_SIMILAR();
                break;
       
          case 14:
                set_focus4(); //Focus On Playlist
                LOAD_TOP_TRACKS();
                break;
       
          /*case 16:
                p.artist = p.eval("%artist% %title%");
                p.browser("https://www.youtube.com/results?search_query=" + encodeURIComponent(p.artist));
                break;*/   
              }
        _menu.Dispose();
        }

//Features Init
    this.features_init = function() {
    for (i = 0; i < this.features.length; i++) {
    switch(this.features[i]) {
    case "metadb":
    this.selection_mode = 1;
    break;
    case "remap":
    this.artist_tf = ("%artist%");
    break;
}
}
}

    this.check_feature = function(f) {
    for (i = 0; i < this.features.length; i++) {
    if (this.features[i] == f) return true;
    }
    return false;
    }

//Eval
this.eval = function(tf) {
    if (!this.metadb || tf == "") return "";
    /*if (fb.IsPlaying && this.metadb.RawPath.indexOf("file://") != 0) {
    return fb.TitleFormat(tf).Eval();
    } else {*/
    return fb.TitleFormat(tf).EvalWithMetadb(this.metadb);
    //}
}

//Console Msg
    this.console = function(message) {
    this.name = "Youtube Radio"
    fb.trace(this.name + ": " + message);
    }

//Trim
    String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
    }   

//Input Box   
this.InputBox = function(prompt, title, value) {
    prompt = prompt.replace(/"/g, '" + Chr(34) + "').replace(/\n/g, '" + Chr(13) + "');
    title = title.replace(/"/g, '" + Chr(34) + "');
    value = value.replace(/"/g, '" + Chr(34) + "');
    var temp_value = this.vb.eval('InputBox' + '("' + prompt + '", "' + title + '", "' + value + '")');
    if (typeof temp_value == "undefined") return value;
    if (temp_value.length == 254) this.MsgBox("Your entry was too long and will be truncated.\n\nSee the WSH panel mod script discussion thread on hydrogenaudio forums for help.", 0, "Youtube Radio");
    return temp_value.trim();
}

//Msg Box
this.MsgBox = function(prompt, buttons, title) {
    prompt = prompt.replace(/"/g, '" + Chr(34) + "').replace(/\n/g, '" + Chr(13) + "');
    title = title.replace(/"/g, '" + Chr(34) + "');
    return this.vb.eval('MsgBox' + '("' + prompt + '", "' + buttons + '", "' + title + '")');
}

//Browser
this.browser = function(command) {
    if (!this.run(command)) this.MsgBox("Unable to launch your default browser.", 0, "Youtube Radio");
}

//Run Command
this.run = function(command) {
    try {
    this.WshShell.Run(command);
    return true;
    } catch(e) {
    return false;
    }
}

//Futures
    this.metadb_func = typeof on_metadb_changed == "function";
this.features = features;
this.dui = window.InstanceType;
this.metadb = fb.GetFocusItem();
this.WshShell = new ActiveXObject("WScript.Shell");
this.fso = new ActiveXObject("Scripting.FileSystemObject");
this.vb = new ActiveXObject("ScriptControl");
this.vb.Language = "VBScript";
this.artist_tf = "%artist%";
this.features_init();
    this.metadb = fb.IsPlaying ? fb.GetNowPlaying() : fb.GetFocusItem();
    if (fb.GetFocusItem())
    {this.artist = fb.TitleFormat(this.artist_tf).EvalWithMetadb(this.metadb);}

}

//Clean Track Name
CLEAN_TRACK_NAME = function (t)
{ try
  {
    return t.split(/\(/g)[0].split(/\[/g)[0].split(/{/g)[0].split(/ Feat./g)[0].split(/ Feat/g)[0].split(/ feat/g)[0].split(/ - /g)[0].trim();
  } catch (e) {}
}

//*********************YT RADIO START**********************

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

//LOAD SIMILAR ARTIST--------------------------------------------
this.LOAD_SIMILAR = function()
{   
if (YT_AUTO=="1")
if (YT_PLS_FOCUS=="1")
if (YT_STATION.indexOf("*")== 0) {LOAD_GENRE()} else
if (xmlhttp != null)
{
url = "http://ws.audioscrobbler.com/2.0/?method=artist.getSimilar&artist=" + encodeURIComponent(YT_STATION) + "&api_key=" + API + "&format=json&limit=" + art_hot + "&autocorrect=1";

xmlhttp.open("GET",url,true);
xmlhttp.setRequestHeader('User-Agent', "foobar2000_script");
xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
        data = xmlhttp.ResponseText;
   
try {
json_data = JSON.parse(data);

//Check Length
ln = json_data.similarartists.artist;
ln = ln.length;

//Select Random Similar Artist
randomnumber = Math.floor(Math.random()*(1-ln)+ln);
var i = randomnumber;
random_sim_art = json_data.similarartists.artist[i].name.replace(/&amp;/g, " \& ");

//Save Similar Artist
YT_SIM_ART = window.SetProperty("YT Similar", random_sim_art);
YT_SIM_ART = random_sim_art;
window.SetProperty("YT Similar", random_sim_art);

        xmlhttp.close;
        LOAD_TRACK();

} catch (err) {xmlhttp.close; p.console("Station doesn't exist!");}       
   
} else
          if (xmlhttp.status == 404) {p.console("HTTP error: " + xmlhttp.status);}
          }}
         
}try {xmlhttp.send();} catch (err) {xmlhttp.close;}
}

//LOAD TRACK----------------------------------------------------
this.LOAD_TRACK = function()
{
if (YT_AUTO=="1")
if (YT_PLS_FOCUS=="1")
if (xmlhttp != null)
{
url = "http://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=" + encodeURIComponent(YT_SIM_ART) + "&api_key=" + API + "&format=json&limit=" + sng_hot + "&autocorrect=1";

xmlhttp.open("GET",url,true);
xmlhttp.setRequestHeader('User-Agent', "foobar2000_script");
xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
        data = xmlhttp.ResponseText;
     
try {
json_data = JSON.parse(data);

//Check Length
ln = json_data.toptracks.track;
ln = ln.length;

//Select Random Track
randomnumber = Math.floor(Math.random()*(1-ln)+ln);
var i = randomnumber;
random_track = json_data.toptracks.track[i].name.replace(/&amp;/g, " \& ");;
random_track = CLEAN_TRACK_NAME(random_track); //Clean Track Name
p.console("" + YT_SIM_ART + " - " + random_track);

//Save Random Track
YT_TRACK = window.SetProperty("YT Track", random_track);
YT_TRACK = random_track;
window.SetProperty("YT Track", random_track);
       
        xmlhttp.close;
        set_focus(); //Focus On Playlist
        do_youtube_search1(decodeURIComponent(YT_SIM_ART), decodeURIComponent(YT_TRACK));
       
} catch (err) {xmlhttp.close; p.console("Artist doesn't have tracks!"); if (YT_STATION.indexOf("*")== 0) {LOAD_GENRE();} else {LOAD_SIMILAR();}}       
       
} else
        if (xmlhttp.status == 404) {p.console("HTTP error: " + xmlhttp.status);}
        }}

}try {xmlhttp.send();} catch (err) {xmlhttp.close;}
}

//TOP TRACKS----------------------------------------------------
this.LOAD_TOP_TRACKS = function()
{
p.artist = p.eval("%artist%");
if (xmlhttp != null)
{   
url = "http://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=" + encodeURIComponent(p.artist) + "&api_key=" + API + "&format=json&limit=50" + "&autocorrect=1";

xmlhttp.open("GET",url,true);
xmlhttp.setRequestHeader('User-Agent', "foobar2000_script");
xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
        data = xmlhttp.ResponseText;
 
try {
json_data = JSON.parse(data);

//Check Length
ln = json_data.toptracks.track;
ln = ln.length;

//List Tracks
for (i = 0; i < ln; i++)
{
list_tracks = json_data.toptracks.track[i].name.replace(/&amp;/g, " \& ");
list_tracks = CLEAN_TRACK_NAME(list_tracks); //Clean Track Name
do_youtube_search1(decodeURIComponent(p.artist), list_tracks);
}

} catch (err) {xmlhttp.close; p.console("Artist doesn't have tracks!");}       
       
} else
        if (xmlhttp.status == 404) {p.console("HTTP error: " + xmlhttp.status);}
        }}

}try {xmlhttp.send();} catch (err) {xmlhttp.close;}
}

//GENRE----------------------------------------------------
this.LOAD_GENRE = function()
{
if (YT_AUTO=="1")
if (YT_PLS_FOCUS=="1")
if (YT_STATION.indexOf("*")== 0)
if (xmlhttp != null)
{
url = "http://ws.audioscrobbler.com/2.0/?method=tag.getTopArtists&tag=" + encodeURIComponent(YT_STATION).replace("*", "") + "&api_key=" + API + "&format=json&limit=" + gnr_hot + "&autocorrect=1";
xmlhttp.open("GET",url,true);
xmlhttp.setRequestHeader('User-Agent', "foobar2000_script");
xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
        data = xmlhttp.ResponseText;
        xmlhttp.Close;
       
try {
json_data = JSON.parse(data);

//Check Length
ln = json_data.topartists.artist;
ln = ln.length;

//Select Random Genre Artist
randomnumber = Math.floor(Math.random()*(1-ln)+ln);
var i = randomnumber;
random_genre_artist = json_data.topartists.artist[i].name.replace(/&amp;/g, " \& ");

//Save Genre Artist
YT_SIM_ART = window.SetProperty("YT Similar", random_genre_artist);
YT_SIM_ART = random_genre_artist;
window.SetProperty("YT Similar", random_genre_artist);

        xmlhttp.close;
        LOAD_TRACK();

} catch (err) {xmlhttp.close; p.console("Station doesn't exist!");}
       
} else
      if (xmlhttp.status == 404) {p.console("HTTP error: " + xmlhttp.status);}
      }}

}try {xmlhttp.send();} catch (err) {xmlhttp.close;}
}

//LOVED----------------------------------------------------
this.LOVED = function()
{
                //List Files
                var arr = utils.Glob(folder_loved + "\\*.*").toArray();
                var a = [];

                for (i = 0; i < arr.length; i++) {
                if (arr[i]) a.push(arr[i]); 
                    }
                //Select Random File
                var randomnumber = Math.floor(Math.random()*Math.max(arr.length));
                i=randomnumber;
               
                file_path = arr[i];
                var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
                var str = tmppath + "\\foobar2000.exe /add ";
                var go = str + '"' + file_path + '"';
               
                //Load File
                set_focus6(); //Focus On Playlist
                var tm = window.SetTimeout(function() {
                p.run(go);
                p.console(file_path);
                window.ClearTimeout™; tm = false;
                }, 50);   
}

//SAME VIDEO-----------------------------------------------
this.LOAD_SAME = function()
    {
      var artist0 = p.eval("%artist%");
      var title0 = p.eval("%title%");
      if(artist0 > "?" && title0 > "?") {set_focus2(); do_youtube_search1(decodeURIComponent(artist0), decodeURIComponent(title0));}
}

//LOAD YOUTUBE VIDEO---------------------------------------
strip_title = function (t1, t2)
{
    try
    {
        if (t1 == t2)
        return t1;
        if (t1.match(RegExp(t2 + "( and | & )", "i")))
        return t1;
        var a = "(by the |by: |by |of |the |feat. |ft. |)";
        var b = "( feat.| ft.|)";
        var t3 = "";
        if (!t2.match(/^the /i))
        {
        t3 = t1.replace(RegExp("[^a-z\\d_)\\]\"]*(" + a + t2 + b + ")[^a-z\\d_(\\[\"]*","gi")," - ").replace(/^[^a-z()\[\]\d\"]*|[^a-z()\[\]\d\"]*$/gi, "");
        }
        else
        {
        var t4 = t2.replace(/^the /i, "")
        t3 = t1.replace(RegExp("[^a-z\\d_)\\]\"]*(" + a + t4 + b + ")[^a-z\\d_(\\[\"]*","gi")," - ").replace(/^[^a-z()\[\]\d\"]*|[^a-z()\[\]\d\"]*$/gi, "");
        }
        return t3.match(/\S/) ? t3 : t1;
    }
    catch (e)
    {
    return t1;
    }
}

convert = function(min)
{
    var parts = min.split(':'),
    minutes = +parts[0],
    seconds = +parts[1];
    return minutes * 60 + seconds;
}

strip = function (t)
{
    try
    {
    t = t.replace(/[\.,\!\?\:;'"\-_]/g,"").toLowerCase();
    return t;
    } catch (e)
    {}
}

clean = function (t)
{
    try
    {
    return t.replace(/'/g, "’").toLowerCase();
    } catch (e) {}
}

youtube_search = function (state_change_callback, p_on_search_finished_callback)
{
        this.xmlhttp = null;
        this.http_callback_funct = null;
        this.ready_state_change_callback = state_change_callback;
        this.search_done = false;
        this.on_search_finished_callback = p_on_search_finished_callback;
        this.yt_link;
        this.search_artist;
        this.search_title;
        this.metadata;

    this.on_state_change = function ()
    {
    if (this.xmlhttp != null && this.xmlhttp.readyState == 4 && this.xmlhttp.status == 200 && this.http_callback_funct != null)
    this.http_callback_funct();
    }

    this.StartSearch = function (p_artist, p_title, p_extra_metadata)
    {
        this.search_artist = p_artist;
        this.search_title = p_title;
        this.metadata = p_extra_metadata;
        this.http_callback_funct = null;
        this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

        var URL = "https://www.youtube.com/results?search_query=" + encodeURIComponent(p_artist + " " + p_title);

        this.http_callback_funct = this.AnalyseSearch;
        this.xmlhttp.open("GET", URL);
        this.xmlhttp.onreadystatechange = this.ready_state_change_callback;
        this.xmlhttp.send();
    }

    this.AnalyseSearch = function ()
    {
        var text = this.xmlhttp.responsetext;
        var doc = new ActiveXObject("htmlfile");
        doc.open();
        var div = doc.createElement("div");
        div.innerHTML = text;
        var data = div.getElementsByTagName("a");
        var url = "";
        var first_match;

        re_test:

        for (var i = 0; i < data.length; i++)
        {
        if (data[i].href.indexOf("about:/watch?v=") == 0)
          {
                i++; //Link

            //Find Title[OLD]
            /*{
            var st = text.indexOf( data[i].href.replace("about:/watch?", "") );
            var str = "a class=\"yt-uix-tile-link yt-ui-ellipsis yt-ui-ellipsis-2 yt-uix-sessionlink spf-link\">";
            st = text.indexOf(str, st) + str.length;
            var et = text.indexOf("</a>", st);
            var youtube_title = text.substr(st, et - st);
            var Y_Title = youtube_title.replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&").replace("'", "'").replace("&quot;", "''").replace("&amp;", "&");
            //p.console("Title: " + Y_Title);
            }*/
           
            //Find Title[NEW]
            Y_Title = data[i].title;
            Remove_duration = Y_Title.substring(Y_Title.lastIndexOf(" - ")+1);
            Y_Title = data[i].title.replace(Remove_duration, "").trim();
            //p.console("Title: " + Y_Title);
               
            //Find Minutes
            var s = text.indexOf( data[i].href.replace("about:/watch?", "") );
            var str = "<span class=\"video-time\" aria-hidden=\"true\">";
            s = text.indexOf(str, s) + str.length;
            var e = text.indexOf("</span>", s);
            var length = text.substr(s, e - s);
            length = convert(length);
            length = length ? length : "";
            if (!first_match)

            {                 
            //Artist Title Stripped If Same As Search Artist
            var stripped_title = strip_title(Y_Title, this.search_artist);
            first_match = "3dydfy://www.youtube.com/watch?" + (this.metadata ? this.metadata + "&" : "") + "fb2k_title=" + encodeURIComponent(stripped_title) + "&3dydfy_alt_length=" + encodeURIComponent(length) + "&fb2k_artist=" + encodeURIComponent(this.search_artist) + "&" + data[i].href.replace("about:/watch?", "");
            }
            //3dydfy
            if (!this.IsGoodMatch(Y_Title))
            continue;

            url = "3dydfy://www.youtube.com/watch?" + (this.metadata ? this.metadata + "&" : "") + "fb2k_title=" + encodeURIComponent(this.search_title) + "&3dydfy_alt_length=" + encodeURIComponent(length) + "&fb2k_artist=" + encodeURIComponent(this.search_artist) + "&" + data[i].href.replace("about:/watch?", "");
            break;
            }
        }

        if (!url.length)
        url = first_match;

        this.yt_link = url;

        doc.close();

        this.on_search_finished_callback(url, this.search_artist, this.search_title);
        }

        this.IsGoodMatch = function (video_name)
        {
        var clean_vid_name = clean(strip(video_name));
        var clean_artist = clean(strip(this.search_artist));
        var clean_title = clean(strip(this.search_title));

        if (clean_vid_name.indexOf(clean_artist) != -1 && clean_vid_name.indexOf(clean_title) != -1 && clean_vid_name.indexOf("full album") == -1)
        {
            //p.console("GOOD MATCH");
            return true;
        }
        else
        {
            //p.console("BAD MATCH");
            return false;
        }
    }

}

//Call Search
do_youtube_search1 = function (p_artist, p_title)
    {
    var yt_search1 = new youtube_search(function ()
    {
    yt_search1.on_state_change();
    }, on_youtube_search1_done);
    yt_search1.StartSearch(p_artist, p_title);
    }

on_youtube_search1_done = function (link, p_artist, p_title)
{
var url2="";
url2 = link;
if (!url2)
{p.console("Track Or Artist - Not Exist!"); LOAD_SIMILAR();}

if (link && link.length)
{
           
//p.console("" + "\"" + link + "\"");
YT_URL = window.SetProperty("YT URL", link);
var tmppath = p.fso.GetFolder(fb.FoobarPath).ShortPath;
var str = tmppath + "\\foobar2000.exe /add ";
var go = str + link;
var tm = window.SetTimeout(function() {
p.run(go);
window.ClearTimeout™; tm = false;
}, 50);
}
    }
//**************************(END)**************************
this.artist = "";

//Set Panels
function pan1() { }
function pan2(x, y, w, h) {}
//---------------------------------------------------------

//Begin--->
var p = new panel("Youtube Radio", ["remap", "metadb"]);
var im = new pan2(0, 0, 0, 0);
var th = new pan1();

on_item_focus_change();
{
}

function on_metadb_changed() {
}

//Buttons---------------------------------------------------

var Buttons;
var g_tooltip = window.CreateTooltip();
var g_down = false;
var btn_down = null;
var cur_btn = null;

ButtonStates = {
normal: 0,
hover: 1,
down: 2
}

function Button(x, y, w, h, img_src, func, tiptext)  {
this.left = x;
this.top = y;
this.w = w;
this.h = h;
this.right = x + w;
this.bottom = y + h;
this.func = func;
this.tiptext = tiptext;
this.state = ButtonStates.normal;
this.img_normal = img_src && img_src.normal ? gdi.Image(img_src.normal) : null;
this.img_hover = img_src && img_src.hover ? gdi.Image(img_src.hover) : this.img_normal;
this.img_down = img_src && img_src.down ? gdi.Image(img_src.down) : this.img_hover;
this.img = this.img_normal;

this.alterImage = function(img_src) {
    this.img_normal = img_src && img_src.normal ? gdi.Image(img_src.normal) : null;
    this.img_hover = img_src && img_src.hover ? gdi.Image(img_src.hover) : this.img_normal;
    this.img_down = img_src && img_src.down ? gdi.Image(img_src.down) : this.img_hover;

    this.changeState(this.state);
}

this.traceMouse = function (x, y) {
    var b = (this.left < x) && (x < this.right) && (this.top < y) && (y < this.bottom);
    if (b)
    g_down ? this.changeState(ButtonStates.down) : this.changeState(ButtonStates.hover);
    else
    this.changeState(ButtonStates.normal);
    return b;
}

this.changeState = function (newstate) {
    if (newstate != this.state)
    window.RepaintRect(this.left, this.top, this.w, this.h);
    this.state = newstate;
    switch (this.state)
    {
    case ButtonStates.normal:
    this.img = this.img_normal;
    break;

    case ButtonStates.hover:
    this.img = this.img_hover;
    break;

    case ButtonStates.down:
    this.img = this.img_down;
    break;

    default:
    this.img = null;
}
}

this.draw = function (gr) {
    this.img && gr.DrawImage(this.img, this.left, this.top, this.w, this.h, 0, 0, this.w, this.h);
}

this.onClick = function () {
    this.func && this.func(x,y);
}

this.onMouseIn = function() {
    g_tooltip.Text = this.tiptext;
    g_tooltip.Activate();
}

this.onMouseOut = function() {
    g_tooltip.Deactivate();
}
}

function buttonsDraw(gr) {
for (i in Buttons) {
    Buttons[i].draw(gr);
}
}

function buttonsTraceMouse(x, y) {
var btn = null;
for (i in Buttons) {
    if (Buttons[i].traceMouse(x, y) && !btn)
    btn = Buttons[i];
}

return btn;
}

function on_mouse_move(x, y) {
var btn = buttonsTraceMouse(x, y);

if (btn != cur_btn) {
    cur_btn && cur_btn.onMouseOut();
    btn && btn.onMouseIn();
}

cur_btn = btn;
}

function on_mouse_lbtn_down(x, y) {
g_down = true;
btn_down = cur_btn;

if (cur_btn) {
    cur_btn.changeState(ButtonStates.down);
}
}

function on_mouse_lbtn_up(x, y) {
if (cur_btn) {
    cur_btn.changeState(ButtonStates.hover);
    if( btn_down == cur_btn )
    cur_btn.onClick(x, y);
}
g_down = false;
}

function on_mouse_leave() {
if (cur_btn) {
    cur_btn.changeState(ButtonStates.normal);
}
}

function on_size() {
ww = window.Width;
wh = window.Height;
    window.Repaint();
}

//Background
this.dui = window.InstanceType;
function on_paint(gr) {

    if (this.dui) {
    col = window.GetColorDUI(1);
    gr.FillSolidRect(0, 0, ww, wh, col);
    }
    else
    {
    col = window.GetColorCUI(3);   
    }

buttonsDraw(gr);

}

function RGB(r,g,b) {
return (0xff000000|(r<<16)|(g<<8)|(b));
}

function on_colors_changed() {
window.Repaint();
}

//Init Buttons--------------------------------------------

//Custom Colour
var custom = RGB(255,255,255);

//Button Width
var bw = 24;

//Button Height
var bh = 20;

//Button Position
var top_margin = 0;
var left_margin = 0;

//Folder Path
try {
var image_path0 = window.GetProperty("Button Path", "<default>");
if (image_path0=="<default>") {folder = fb.ProfilePath + "buttons";}
if (image_path0=="") {folder = fb.ProfilePath + "buttons";}
if (image_path0.indexOf(":\\") > 0) {folder = image_path0;}
var image_path = (folder + "\\");
} catch (err) {fb.trace("Youtube Radio: " + "TypeError: 'button path' undefined");}

//These 2 Lines Of Code Lock The Panel Size.
//window.MinWidth = window.MaxWidth = 24;
//window.MinHeight = window.MaxHeight = 20;

Buttons = {
but1: new Button(left_margin,top_margin,bw,bh, {normal: image_path + "youtube0.png", hover: image_path + "youtube1.png"}, function(){
    p.rbtn_up(24, 17);
    }, "Youtube")

}

function on_mouse_rbtn_up(x, y) {
return true;
}


Foobar Youtube Radio

Reply #107
I haven't converted AppendMenuItem() to the new AppendTo() method, because i have some scripts that need to work in older WSH, changing this is not really necessary, as the old method continues to work in WSH 1.5.6.


yes but the "new" method works in v1.5.0 or above so scripts can easily be updated to support both. i suppose if you're clinging on to those ancient hacked builds of 1.4.something that allow transparency, then it's a problem.

 

Foobar Youtube Radio

Reply #108
I haven't converted AppendMenuItem() to the new AppendTo() method, because i have some scripts that need to work in older WSH, changing this is not really necessary, as the old method continues to work in WSH 1.5.6.


yes but the "new" method works in v1.5.0 or above so scripts can easily be updated to support both. i suppose if you're clinging on to those ancient hacked builds of 1.4.something that allow transparency, then it's a problem.


Yes i have some scripts that work only in 1.4, but since i'm now using DUI, i will update all...

Foobar Youtube Radio

Reply #109
Updated: Link>
It seems that ''artist.getSimilar'' API metod is down at the moment, so script wont work untill this be fixed by last.fm..

Foobar Youtube Radio

Reply #110
you'd think after 2 months they'd start fixing stuff, not find new things to break.


Foobar Youtube Radio

Reply #112
New version: Link>

Updates due to changes in tags handling in foo_youtube component.
-Fixed, script sometimes load full playlist instead of single file (if url has ''&list'' in path).
-Replaced '.fb' with '.plman' to support Marc WSH panel mod 1.6.0.