Changeset 87c76c20237a663506a2deed9f8db9af732fee47
- Timestamp:
- 11/12/07 23:00:47 (10 months ago)
- git-parent:
- Files:
-
- modules/misc/lua/Modules.am (modified) (1 diff)
- modules/misc/lua/intf.c (modified) (9 diffs)
- modules/misc/lua/sd.c (added)
- modules/misc/lua/vlc.h (modified) (3 diffs)
- share/http-lua/dialogs/playlist (modified) (2 diffs)
- share/http-lua/requests/playlist.xml (modified) (1 diff)
- share/http-lua/requests/status.xml (modified) (2 diffs)
- share/luaintf/rc.lua (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
modules/misc/lua/Modules.am
re10d431 r87c76c2 1 SOURCES_lua = playlist.c meta.c intf.c vlc.c vlc.h callbacks.c objects.c variables.c configuration.c net.c vlm.c httpd.c acl.c 1 SOURCES_lua = playlist.c meta.c intf.c vlc.c vlc.h callbacks.c objects.c variables.c configuration.c net.c vlm.c httpd.c acl.c sd.c modules/misc/lua/intf.c
re10d431 r87c76c2 54 54 * Internal lua<->vlc utils 55 55 *****************************************************************************/ 56 static inlineplaylist_t *vlclua_get_playlist_internal( lua_State *L )56 playlist_t *vlclua_get_playlist_internal( lua_State *L ) 57 57 { 58 58 vlc_object_t *p_this = vlclua_get_this( L ); … … 356 356 } 357 357 358 static int vlclua_playlist_skip( lua_State * L ) 359 { 360 int i_skip = luaL_checkint( L, 1 ); 361 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 362 playlist_Skip( p_playlist, i_skip ); 363 vlc_object_release( p_playlist ); 364 return 0; 365 } 366 358 367 static int vlclua_playlist_play( lua_State * L ) 359 368 { 360 369 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 361 370 playlist_Play( p_playlist ); 371 vlc_object_release( p_playlist ); 372 return 0; 373 } 374 375 static int vlclua_playlist_pause( lua_State * L ) 376 { 377 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 378 playlist_Pause( p_playlist ); 362 379 vlc_object_release( p_playlist ); 363 380 return 0; … … 407 424 static int vlclua_playlist_goto( lua_State * L ) 408 425 { 409 /* XXX: logic copied from rc.c ... i'm not sure that it's ok as it 410 * implies knowledge of the playlist internals. */ 411 playlist_t *p_playlist; 412 int i_size; 413 playlist_item_t *p_item, *p_parent; 414 415 int i_pos; 416 if( lua_gettop( L ) != 1 ) return vlclua_error( L ); 417 i_pos = luaL_checkint( L, -1 ); 418 lua_pop( L, 1 ); 419 if( i_pos <= 0 ) return 0; 420 421 p_playlist = vlclua_get_playlist_internal( L ); 422 /* The playlist stores 2 times the same item: onelevel & category */ 423 i_size = p_playlist->items.i_size / 2; 424 425 if( i_pos > i_size ) 426 { 427 vlc_object_release( p_playlist ); 428 return 0; 429 } 430 431 p_item = p_parent = p_playlist->items.p_elems[i_pos*2-1]; 432 while( p_parent->p_parent ) 433 p_parent = p_parent->p_parent; 434 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VLC_TRUE, 435 p_parent, p_item ); 436 437 vlc_object_release( p_playlist ); 438 lua_pushboolean( L, 1 ); 439 return 1; 426 int i_id = luaL_checkint( L, 1 ); 427 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 428 int i_ret = playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 429 VLC_TRUE, NULL, 430 playlist_ItemGetById( p_playlist, i_id, 431 VLC_TRUE ) ); 432 vlc_object_release( p_playlist ); 433 return vlclua_push_ret( L, i_ret ); 440 434 } 441 435 … … 464 458 } 465 459 466 static int vlclua_playlist_get( lua_State *L ) 467 { 468 /* TODO: make it possible to get the tree playlist */ 469 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 470 playlist_item_t *p_root; 471 int i; 472 if( lua_isboolean( L, 1 ) && lua_toboolean( L, 1 ) ) 473 p_root = p_playlist->p_ml_onelevel; /* media library */ 474 else 475 p_root = p_playlist->p_local_onelevel; /* local/normal playlist */ 476 lua_createtable( L, p_root->i_children, 0 ); 477 for( i = 0; i < p_root->i_children; i++ ) 478 { 479 playlist_item_t *p_item = p_root->pp_children[i]; 480 input_item_t *p_input = p_item->p_input; 481 lua_pushinteger( L, i+1 ); 482 lua_newtable( L ); 460 static void push_playlist_item( lua_State *L, playlist_item_t *p_item ); 461 static void push_playlist_item( lua_State *L, playlist_item_t *p_item ) 462 { 463 input_item_t *p_input = p_item->p_input; 464 int i_flags = p_item->i_flags; 465 lua_newtable( L ); 466 lua_pushinteger( L, p_item->i_id ); 467 lua_setfield( L, -2, "id" ); 468 lua_newtable( L ); 469 #define CHECK_AND_SET_FLAG( name, label ) \ 470 if( i_flags & PLAYLIST_ ## name ## _FLAG ) \ 471 { \ 472 lua_pushboolean( L, 1 ); \ 473 lua_setfield( L, -2, #label ); \ 474 } 475 CHECK_AND_SET_FLAG( SAVE, save ) 476 CHECK_AND_SET_FLAG( SKIP, skip ) 477 CHECK_AND_SET_FLAG( DBL, disabled ) 478 CHECK_AND_SET_FLAG( RO, ro ) 479 CHECK_AND_SET_FLAG( REMOVE, remove ) 480 CHECK_AND_SET_FLAG( EXPANDED, expanded ) 481 #undef CHECK_AND_SET_FLAG 482 lua_setfield( L, -2, "flags" ); 483 if( p_input ) 484 { 483 485 lua_pushstring( L, p_input->psz_name ); 484 486 lua_setfield( L, -2, "name" ); … … 493 495 lua_setfield( L, -2, "nb_played" ); 494 496 /* TODO: add (optional) info categories, meta, options, es */ 497 } 498 if( p_item->i_children >= 0 ) 499 { 500 int i; 501 lua_createtable( L, p_item->i_children, 0 ); 502 for( i = 0; i < p_item->i_children; i++ ) 503 { 504 push_playlist_item( L, p_item->pp_children[i] ); 505 lua_rawseti( L, -2, i+1 ); 506 } 507 lua_setfield( L, -2, "children" ); 508 } 509 } 510 511 static int vlclua_playlist_get( lua_State *L ) 512 { 513 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 514 int b_category = luaL_optboolean( L, 2, 1 ); /* Default to tree playlist (discared when 1st argument is a playlist_item's id) */ 515 playlist_item_t *p_item = NULL; 516 517 if( lua_isnumber( L, 1 ) ) 518 { 519 int i_id = lua_tointeger( L, 1 ); 520 p_item = playlist_ItemGetById( p_playlist, i_id, VLC_TRUE ); 521 if( !p_item ) 522 { 523 vlc_object_release( p_playlist ); 524 return 0; /* Should we return an error instead? */ 525 } 526 } 527 else if( lua_isstring( L, 1 ) ) 528 { 529 const char *psz_what = lua_tostring( L, 1 ); 530 if( !strcasecmp( psz_what, "normal" ) 531 || !strcasecmp( psz_what, "playlist" ) ) 532 p_item = b_category ? p_playlist->p_local_category 533 : p_playlist->p_local_onelevel; 534 else if( !strcasecmp( psz_what, "ml" ) 535 || !strcasecmp( psz_what, "media library" ) ) 536 p_item = b_category ? p_playlist->p_ml_category 537 : p_playlist->p_ml_onelevel; 538 else if( !strcasecmp( psz_what, "root" ) ) 539 p_item = b_category ? p_playlist->p_root_category 540 : p_playlist->p_root_onelevel; 541 else 542 { 543 int i; 544 for( i = 0; i < p_playlist->i_sds; i++ ) 545 { 546 if( !strcasecmp( psz_what, 547 p_playlist->pp_sds[i]->p_sd->psz_module ) ) 548 { 549 p_item = b_category ? p_playlist->pp_sds[i]->p_cat 550 : p_playlist->pp_sds[i]->p_one; 551 break; 552 } 553 } 554 if( !p_item ) 555 { 556 vlc_object_release( p_playlist ); 557 return 0; /* Should we return an error instead? */ 558 } 559 } 560 } 561 else 562 { 563 p_item = b_category ? p_playlist->p_root_category 564 : p_playlist->p_root_onelevel; 565 } 566 push_playlist_item( L, p_item ); 567 vlc_object_release( p_playlist ); 568 return 1; 569 } 570 #if 0 571 int s; 572 lua_createtable( L, 0, 2 + p_playlist->i_sds ); 573 for( s = -2; s < p_playlist->i_sds; s++ ) 574 { 575 playlist_item_t *p_root; 576 switch( s ) 577 { 578 case -2: 579 /* local/normal playlist */ 580 lua_pushstring( L, "local" ); 581 p_root = p_playlist->p_local_onelevel; 582 break; 583 case -1: 584 /* media library */ 585 lua_pushstring( L, "ml" ); 586 p_root = p_playlist->p_ml_onelevel; 587 break; 588 default: 589 lua_pushstring( L, p_playlist->pp_sds[s]->p_sd->psz_module ); 590 printf("%s\n", p_playlist->pp_sds[s]->p_sd->psz_module ); 591 p_root = p_playlist->pp_sds[s]->p_one; 592 break; 593 } 594 printf("s = %d\n", s); 595 printf("children = %d\n", p_root->i_children ); 596 push_playlist_item( L, p_root ); 495 597 lua_settable( L, -3 ); 496 598 } 497 vlc_object_release( p_playlist ); 498 return 1; 599 printf("done\n"); 600 #endif 601 602 static int vlclua_playlist_search( lua_State *L ) 603 { 604 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 605 const char *psz_string = luaL_optstring( L, 1, "" ); 606 int b_category = luaL_optboolean( L, 2, 1 ); /* default to category */ 607 playlist_LiveSearchUpdate( p_playlist, 608 b_category ? p_playlist->p_root_category 609 : p_playlist->p_root_onelevel, 610 psz_string ); 611 push_playlist_item( L, p_playlist->p_root_category ); 612 vlc_object_release( p_playlist ); 613 return 1; 614 } 615 616 static int vlc_sort_key_from_string( const char *psz_name ) 617 { 618 static const struct 619 { 620 const char *psz_name; 621 int i_key; 622 } pp_keys[] = 623 { { "id", SORT_ID }, 624 { "title", SORT_TITLE }, 625 { "title nodes first", SORT_TITLE_NODES_FIRST }, 626 { "artist", SORT_ARTIST }, 627 { "genre", SORT_GENRE }, 628 { "random", SORT_RANDOM }, 629 { "duration", SORT_DURATION }, 630 { "title numeric", SORT_TITLE_NUMERIC }, 631 { "album", SORT_ALBUM }, 632 { NULL, -1 } }; 633 int i; 634 for( i = 0; pp_keys[i].psz_name; i++ ) 635 { 636 if( !strcmp( psz_name, pp_keys[i].psz_name ) ) 637 return pp_keys[i].i_key; 638 } 639 return -1; 499 640 } 500 641 … … 502 643 { 503 644 /* allow setting the different sort keys */ 504 return 0; 645 int i_mode = vlc_sort_key_from_string( luaL_checkstring( L, 1 ) ); 646 if( i_mode == -1 ) 647 return luaL_error( L, "Invalid search key." ); 648 int i_type = luaL_optboolean( L, 2, 0 ) ? ORDER_REVERSE : ORDER_NORMAL; 649 int b_category = luaL_optboolean( L, 3, 1 ); /* default to category */ 650 playlist_t *p_playlist = vlclua_get_playlist_internal( L ); 651 playlist_item_t *p_root = b_category ? p_playlist->p_local_category 652 : p_playlist->p_local_onelevel; 653 int i_ret = playlist_RecursiveNodeSort( p_playlist, p_root, i_mode, 654 i_type ); 655 vlc_object_release( p_playlist ); 656 return vlclua_push_ret( L, i_ret ); 505 657 } 506 658 … … 656 808 { "prev", vlclua_playlist_prev }, 657 809 { "next", vlclua_playlist_next }, 810 { "skip", vlclua_playlist_skip }, 658 811 { "play", vlclua_playlist_play }, 812 { "pause", vlclua_playlist_pause }, 659 813 { "stop", vlclua_playlist_stop }, 660 814 { "clear", vlclua_playlist_clear }, … … 667 821 { "enqueue", vlclua_playlist_enqueue }, 668 822 { "get", vlclua_playlist_get }, 823 { "search", vlclua_playlist_search }, 824 { "sort", vlclua_playlist_sort }, 825 669 826 { "stats", vlclua_input_stats }, 827 828 { NULL, NULL } 829 }; 830 831 static luaL_Reg p_reg_sd[] = 832 { 833 { "get_services_names", vlclua_sd_get_services_names }, 834 { "add", vlclua_sd_add }, 835 { "remove", vlclua_sd_remove }, 836 { "is_loaded", vlclua_sd_is_loaded }, 670 837 671 838 { NULL, NULL } … … 889 1056 luaL_register_submodule( L, "msg", p_reg_msg ); 890 1057 luaL_register_submodule( L, "playlist", p_reg_playlist ); 1058 luaL_register_submodule( L, "sd", p_reg_sd ); 891 1059 luaL_register_submodule( L, "volume", p_reg_volume ); 892 1060 luaL_register_submodule( L, "osd", p_reg_osd ); modules/misc/lua/vlc.h
re10d431 r87c76c2 87 87 } 88 88 89 static inline int luaL_optboolean( lua_State *L, int narg, int def ) 90 { 91 return luaL_opt( L, luaL_checkboolean, narg, def ); 92 } 93 89 94 static inline const void *luaL_checklightuserdata( lua_State *L, int narg ) 90 95 { … … 120 125 int vlclua_object_find_name( lua_State *L ); 121 126 127 vlc_object_t * vlclua_get_this( lua_State * ); 128 playlist_t *vlclua_get_playlist_internal( lua_State * ); 129 122 130 int vlclua_add_callback( lua_State * ); 123 131 int vlclua_del_callback( lua_State * ); … … 164 172 int vlclua_acl_load_file( lua_State * ); 165 173 174 int vlclua_sd_get_services_names( lua_State * ); 175 int vlclua_sd_add( lua_State * ); 176 int vlclua_sd_remove( lua_State * ); 177 int vlclua_sd_is_loaded( lua_State * ); 178 166 179 167 180 /***************************************************************************** 168 181 * Lua function bridge 169 182 *****************************************************************************/ 170 vlc_object_t * vlclua_get_this( lua_State * );171 183 #define vlclua_error( L ) luaL_error( L, "VLC lua error in file %s line %d (function %s)", __FILE__, __LINE__, __func__ ) 172 184 int vlclua_push_ret( lua_State *, int i_error ); share/http-lua/dialogs/playlist
re10d431 r87c76c2 62 62 </button> 63 63 <div id="menu_sort" class="menu" > 64 <button class="menuout" onclick="pl_sort(1,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Name ascending" >Name</button><br/> 65 <button class="menuout" onclick="pl_sort(1,1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Name descending" >Name reverse</button><br/> 66 <button class="menuout" onclick="pl_sort(3,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Author ascending" >Author</button><br/> 67 <button class="menuout" onclick="pl_sort(3,1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Author ascending" >Author reverse</button><br/> 68 <button class="menuout" onclick="pl_sort(5,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Randomize" >Random</button><br/> 69 <button class="menuout" onclick="pl_sort(7,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Track number" >Track number</button><br/> 70 <button class="menuout" onclick="pl_sort(0,0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Id ascending" >Id</button><br/> 71 <button class="menuout" onclick="pl_sort(0,1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Id descending" >Id reverse</button><br/> 64 <button class="menuout" onclick="pl_sort('title',0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Title ascending" >Title</button><br/> 65 <button class="menuout" onclick="pl_sort('title',1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Title descending" >Title reverse</button><br/> 66 <button class="menuout" onclick="pl_sort('artist',0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Artist ascending" >Artist</button><br/> 67 <button class="menuout" onclick="pl_sort('artist',1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Artist ascending" >Artist reverse</button><br/> 68 <button class="menuout" onclick="pl_sort('album',0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Album ascending" >Album</button><br/> 69 <button class="menuout" onclick="pl_sort('album',1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Album ascending" >Album reverse</button><br/> 70 <button class="menuout" onclick="pl_sort('genre',0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Genre ascending" >Genre</button><br/> 71 <button class="menuout" onclick="pl_sort('genre',1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Genre ascending" >Genre reverse</button><br/> 72 <button class="menuout" onclick="pl_sort('random',0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Randomize" >Random</button><br/> 73 <button class="menuout" onclick="pl_sort('id',0);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Id ascending" >Id</button><br/> 74 <button class="menuout" onclick="pl_sort('id',1);hide_menu('menu_sort');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" title="Sort by Id descending" >Id reverse</button><br/> 72 75 </div> 73 76 </td> … … 78 81 </button> 79 82 <div id="menu_sd" class="menu" > 80 <?vlc --[[ FIXME81 <vlc id="rpn" param1="services_discovery" />82 <vlc id="foreach" param1="sd" param2="object" />83 <button onclick="pl_sd('<vlc id="value" param1="sd" />');hide_menu('menu_sd');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" class="menuout" title="Toggle <vlc id="value" param1="sd.name" />" ><vlc id="value" param1="sd.name" /></button><br/>84 <vlc id="end" />85 ]]?>83 <?vlc 84 local sd = vlc.sd.get_services_names() 85 for n,ln in pairs(sd) do 86 print([[<button onclick="pl_sd(']]..n..[[');hide_menu('menu_sd');" onmouseover="setclass(this,'menuover');" onmouseout="setclass(this,'menuout');" class="menuout" title="Toggle ]]..ln..[[" >]]..ln..[[</button><br/>]]) 87 end 88 ?> 86 89 </div> 87 90 </td> share/http-lua/requests/playlist.xml
re10d431 r87c76c2 26 26 ]] ?> 27 27 28 <node id="0" name="Undefined" ro="ro">29 28 <?vlc 30 local playlist = vlc.playlist.get() 31 for i,item in ipairs(playlist) do 32 local name, path = vlc.convert_xml_special_chars(item.name,item.path) 33 print("<leaf id='"..tostring(i).."' uri='"..path.."' name='"..name.."' ro='ro' duration='"..tostring(item.duration).."'/>") 29 --[[<node id="0" name="Undefined" ro="ro">]] 30 function print_playlist(item) 31 if item.children then 32 local name = vlc.convert_xml_special_chars(item.name) 33 print("<node id=\""..tostring(item.id).."\" name=\""..name.."\" ro=\""..(item.flags.ro and "ro" or "rw").."\">") 34 for _, c in ipairs(item.children) do 35 print_playlist(c) 36 end 37 print("</node>") 38 else 39 local name, path = vlc.convert_xml_special_chars(item.name,item.path or "") 40 print("<leaf id='"..tostring(item.id).."' uri='"..path.."' name='"..name.."' ro='"..(item.flags.ro and "ro" or "rw").."' duration='"..tostring(item.duration).."'/>") 41 end 34 42 end 43 function a(t,pre) 44 local pre = pre or "" 45 for k,v in pairs(t) do 46 vlc.msg.err(pre..tostring(k).." : "..tostring(v)) 47 if type(v) == "table" then 48 a(v,pre.." ") 49 end 50 end 51 end 52 --[[ 53 for cat,pl in pairs(p) do 54 print("<node id=\"-1\" name=\""..cat.."\" ro=\"ro\">") 55 print_playlist(pl) 56 print("</node>") 57 end 58 --]] 59 local p = vlc.playlist.get() 60 -- a(p) Uncomment to debug 61 print_playlist(p) 35 62 ?> 36 </node>37 63 38 64 <?vlc --[[ 65 </node> 39 66 <node id="9" name="Nevermind" ro="rw"> 40 67 <leaf id="10" current="current" uri="file:///mnt/stuff/media/Nirvana/Nevermind/01 - Smells Like Teen Spirit.mp3" name="Smells Like Teen Spirit" ro="rw" duration="-1"/> share/http-lua/requests/status.xml
re10d431 r87c76c2 65 65 vlc.playlist.clear() 66 66 elseif command == "pl_sort" then 67 vlc. msg.err("FIXME: pl_sort unimplemented")67 vlc.playlist.sort( val, id > 0 ) 68 68 elseif command == "pl_random" then 69 69 vlc.playlist.random() … … 73 73 vlc.playlist.repeat_() 74 74 elseif command == "pl_sd" then 75 vlc.msg.err("FIXME: pl_sd unimplemented") 76 --[[ 77 <vlc id="if" param1="val value services_discovery_is_loaded" /> 78 <vlc id="rpn" param1="val value services_discovery_remove" /> 79 <vlc id="else" /> 80 <vlc id="rpn" param1="val value services_discovery_add" /> 81 <vlc id="end" /> 82 ]] 75 if vlc.sd.is_loaded(val) then 76 vlc.sd.remove(val) 77 else 78 vlc.sd.add(val) 79 end 83 80 elseif command == "fullscreen" then 84 81 vlc.fullscreen() share/luaintf/rc.lua
re10d431 r87c76c2 165 165 166 166 function playlist(name,client,arg) 167 -- TODO: add possibility to filter playlist items using a mask 167 function playlist0(item,prefix) 168 local prefix = prefix or "" 169 if not item.flags.disabled then 170 local str = "| "..prefix..tostring(item.id).." - "..item.name 171 if item.duration > 0 then 172 str = str.." ("..common.durationtostring(item.duration)..")" 173 end 174 if item.nb_played > 0 then 175 str = str.." [played "..tostring(item.nb_played).." time" 176 if item.nb_played > 1 then 177 str = str .. "s" 178 end 179 str = str .. "]" 180 end 181 client:append(str) 182 end 183 if item.children then 184 for _, c in ipairs(item.children) do 185 playlist0(c,prefix.." ") 186 end 187 end 188 end 168 189 local playlist 169 if arg == "ml" then 170 playlist = vlc.playlist.get(true) 171 client:append("+----[ Playlist - Media Library ]") 172 else 173 playlist = vlc.playlist.get() 174 client:append("+----[ Playlist ]") 175 end 176 for i, item in pairs(playlist) do 177 local str = "| "..tostring(i).." - "..item.name 178 if item.duration > 0 then 179 str = str.." ("..common.durationtostring(item.duration)..")" 180 end 181 if item.nb_played > 0 then 182 str = str.." played "..tostring(item.nb_played).." time" 183 if item.nb_played > 1 then 184 str = str .. "s" 185 end 186 end 187 client:append(str) 188 end 189 client:append("+----[ End of playlist ]") 190 if name == "search" then 191 playlist = vlc.playlist.search(arg or "") 192 else 193 if tonumber(arg) then 194 print "number" 195 playlist = vlc.playlist.get(tonumber(arg)) 196 elseif arg then 197 print "string" 198 playlist = vlc.playlist.get(arg) 199 else 200 playlist = vlc.playlist.get() 201 end 202 end 203 if name == "search" then 204 client:append("+----[ Search - "..(arg or "`reset'").." ]") 205 else 206 client:append("+----[ Playlist - "..playlist.name.." ]") 207 end 208 if playlist.children then 209 for _, item in ipairs(playlist.children) do 210 playlist0(item) 211 end 212 else 213 playlist0(playlist) 214 end 215 if name == "search" then 216 client:append("+----[ End of search - Use `search' to reset ]") 217 else 218 client:append("+----[ End of playlist ]") 219 end 220 end 221 222 function playlist_sort(name,client,arg) 223 if not arg then 224 client:append("Valid sort keys are: id, title, artist, genre, random, duration, album.") 225 else 226 vlc.playlist.sort(arg) 227 end 228 end 229 230 function services_discovery(name,client,arg) 231 if arg then 232 if vlc.sd.is_loaded(arg) then 233 vlc.sd.remove(arg) 234 client:append(arg.." disabled.") 235 else 236 vlc.sd.add(arg) 237 client:append(arg.." enabled.") 238 end 239 else 240 local sd = vlc.sd.get_services_names() 241 client:append("+----[ Services discovery ]") 242 for n,ln in pairs(sd) do 243 local status 244 if vlc.sd.is_loaded(n) then 245 status = "enabled" 246 else 247 status = "disabled" 248 end 249 client:append("| "..n..": " .. ln .. " (" .. status .. ")") 250 end 251 client:append("+----[ End of services discovery ]") 252 end 190 253 end 191 254 … … 339 402 { "enqueue"; { func = add; args = "XYZ"; help = "queue XYZ to playlist" } }; 340 403 { "playlist"; { func = playlist; help = "show items currently in playlist" } }; 404 { "search"; { func = playlist; args = "[string]"; help = "search for items in playlist (or reset search)" } }; 405 { "sort"; { func = playlist_sort; args = "key"; help = "sort the playlist" } }; 406 { "sd"; { func = services_discovery; args = "[sd]"; help = "show services discovery or toggle" } }; 341 407 { "play"; { func = skip2(vlc.playlist.play); help = "play stream" } }; 342 408 { "stop"; { func = skip2(vlc.playlist.stop); help = "stop stream" } };
