远程WEB控制MP3播放器设计(基于mini2440)

网上有很多 基于mini2440的MP3播放器设计的资料,多是按键控制,这里博主做了些轻微改动,利用远程WEB来控制MP3播放,具体怎么实现,下面会给出,大家先看看效果:

WEB界面:


后台运行:


因为不是什么课程设计报告,博主就不阐述的那么详细,这个设计主要有三部分组成:

1、WEB控制端(就是浏览器);

2、WEB服务器端(将mini2440开发板作为服务器,其中移植了BOA服务器,这里不做详细介绍,大家网上搜一搜,好多资料,BOA服务器是嵌入式设备中用的比较多的WEB服务器);

3、应用程序部分(就是MP3播放器);

下面将代码列出,就其中重要部分进行详解:

MP3播放代码如下:

[cpp]  view plain  copy
  1. /* 
  2.  *     SD卡mp3播放器控制程序 
  3.  *     功能: 
  4.              k1:播放、暂停 
  5.              k2:停止播放 
  6.              k3:上一首 
  7.              k4:下一首 
  8.  *     附加:歌曲自动循环播放SD卡/sdcard/song目录中mp3歌曲 
  9.  */  
  10.    
  11. #include <stdio.h>  
  12. #include <stdlib.h>  
  13. #include <unistd.h>  
  14. #include <sys/ioctl.h>  
  15. #include <sys/types.h>  
  16. #include <sys/stat.h>  
  17. #include <fcntl.h>  
  18. #include <signal.h>  
  19. #include <sys/select.h>  
  20. #include <sys/time.h>  
  21. #include <errno.h>  
  22. #include <sys/wait.h>  
  23. #include <string.h>  
  24. #include <sys/ipc.h>  
  25. #include <sys/shm.h>  
  26.   
  27. /*共享内存申请标记*/  
  28. #define PERM S_IRUSR|S_IWUSR                                                      
  29.   
  30. /*双向循环列表:存放歌曲名*/  
  31. struct song               
  32. {  
  33.     char songname[20];  
  34.     struct song *prev;  
  35.     struct song *next;  
  36. };  
  37.   
  38. /*孙子进程id号*/  
  39. pid_t gradchild;  
  40.   
  41. /*子进程id号*/  
  42. pid_t pid;  
  43.   
  44. /*共享内存描述标记*/  
  45. int shmid;  
  46. char *p_addr;  
  47. /*共享内存内容格式*/  
  48. /*|gradchild(孙子进程PID) |+ |空一个字节|+ currentsong(当前播放列表的节点指针)|*/  
  49.   
  50. /*播放标记*/  
  51. int first_key=1;  
  52. int play_flag=0;  
  53.   
  54. /************************************************* 
  55. Function name: play 
  56. Parameter    : struct song * 
  57. Description  : 播放函数 
  58. Return       : void 
  59. Argument     : void 
  60. **************************************************/  
  61. void play(struct song *currentsong)  
  62. {  
  63.     pid_t fd;  
  64.     char *c_addr;  
  65.     char *p;  
  66.     int len;  
  67.     char my_song[30]="/sdcard/song/";   
  68.     while(currentsong)  
  69.     {  
  70.         /*创建子进程,即孙子进程*/  
  71.         fd = fork();  
  72.         if(fd == -1)  
  73.         {     
  74.             perror("fork");  
  75.             exit(1);  
  76.         }  
  77.         else if(fd == 0)   
  78.         {  
  79.             /*把歌曲名加上根路径*/  
  80.             strcat(my_song,currentsong->songname);   
  81.             p = my_song;  
  82.             len = strlen(p);  
  83.             /*去掉文件名最后的'\n'*/  
  84.             my_song[len-1]='\0';  
  85.   
  86.             printf("THIS SONG IS %s\n",my_song);  
  87.                       /*运行madplay播放器,播放MP3*/  
  88.                      system("printf(" THIS SONG IS %s\n", $my_song) >>/tmp/songname");  
  89.           
  90.               
  91.             execl("/bin/madplay","madplay",my_song,NULL);  
  92.             printf("\n\n\n");  
  93.         }  
  94.         else   
  95.         {  
  96.             /*内存映射*/  
  97.               
  98.             c_addr = shmat(shmid,0,0);  
  99.   
  100.               
  101.             memcpy(c_addr,&fd,sizeof(pid_t));  
  102.             memcpy(c_addr + sizeof(pid_t)+1,¤tsong,4);  
  103.   
  104.             /*使用wait阻塞子进程,直到孙子进程播放完才能被唤醒; 
  105.               当被唤醒时,表示播放MP3期间没有按键按下,则继续顺序播放下一首MP3*/  
  106.               
  107.             if(fd == wait(NULL))  
  108.             {  
  109.                 currentsong = currentsong->next;  
  110.                 printf("THE NEXT SONG IS %s\n",currentsong->songname);  
  111.             }  
  112.         }  
  113.     }  
  114. }  
  115.   
  116. /************************************************* 
  117. Function name: creat_song_list 
  118. Parameter    : void 
  119. Description  : 创建歌曲名的双向循环链表 
  120. Return       : struct song * 
  121. Argument     : void 
  122. **************************************************/  
  123. struct song *creat_song_list(void)  
  124. {     
  125.     FILE *fd;  
  126.     size_t size;  
  127.     size_t len;  
  128.     char *line = NULL;  
  129.     struct song *head;  
  130.     struct song *p1;  
  131.     struct song *p2;  
  132.     system("ls /sdcard/song >song_list");  
  133.     fd = fopen("song_list","r");  
  134.   
  135.     p1 = (struct song *)malloc(sizeof(struct song));  
  136.   
  137.     printf("==================================song list=====================================\n");  
  138.     system("ls /sdcard/song");    
  139.     printf("\n");  
  140.     printf("================================================================================\n");  
  141.     size = getline(&line,&len,fd);  
  142.   
  143.     strncpy(p1->songname,line,strlen(line));  
  144.     head = p1;  
  145.     while((size = getline(&line,&len,fd)) != -1) //从文件中读取一行,直到出错或者到文件尾EOF返回-1  
  146.     {     
  147.         p2 = p1;  
  148.         p1 = (struct song *)malloc(sizeof(struct song));  
  149.         strncpy(p1->songname,line,strlen(line));  
  150.         p2->next = p1;  
  151.         p1->prev = p2;     
  152.     }  
  153.     //此时到了文件尾,若是循环列表,则下一首为head,即第一首   
  154.     p1->next = head;  
  155.     head->prev = p1;  
  156.     p1 = NULL;  
  157.     p2 = NULL;  
  158.     system("rm -rf song_list");  
  159.     return head;  
  160. }  
  161. /************************************************* 
  162. Function name: startplay 
  163. Parameter    : pid_t *,struct song * 
  164. Description  : 开始播放函数 
  165. Return       : void 
  166. Argument     : void 
  167. **************************************************/  
  168. void startplay(pid_t *childpid,struct song *my_song)  
  169. {  
  170.     pid_t pid;  
  171.     int ret;  
  172.     /*创建子进程*/  
  173.     pid = fork();  
  174.   
  175.     if(pid > 0) //父进程  
  176.     {  
  177.         *childpid = pid; //子进程PID初始化  
  178.         play_flag = 1;  
  179.         sleep(1);  
  180.         /*读取共享内存保存的pid,初始化孙子进程的pid*/  
  181.         memcpy(&gradchild,p_addr,sizeof(pid_t));  
  182.           
  183.     }  
  184.     else if(0 == pid) //子进程  
  185.     {     
  186.         /*子进程播放MP3函数*/  
  187.         play(my_song);  
  188.     }  
  189. }  
  190. /************************************************* 
  191. Function name: my_pause 
  192. Parameter    : pid_t 
  193. Description  : 暂停函数 
  194. Return       : void 
  195. Argument     : void 
  196. **************************************************/  
  197. void my_pause(pid_t pid)  
  198. {  
  199.     printf("=======================PAUSE!PRESS K1 TO CONTINUE===================\n");  
  200.     kill(pid,SIGSTOP); //对孙子进程发送SIGSTOP信号  
  201.     play_flag = 0;  
  202. }  
  203.   
  204. /************************************************* 
  205. Function name: my_pause 
  206. Parameter    : pid_t 
  207. Description  : 停止播放函数 
  208. Return       : void 
  209. Argument     : void 
  210. Autor & date : Hanson  11,04, 05 
  211. **************************************************/  
  212. void my_stop(pid_t g_pid)  
  213. {  
  214.   
  215.     printf("=======================STOP!PRESS K1 TO START PLAY===================\n");  
  216.     kill(g_pid,SIGKILL); //对孙子进程发送SIGKILL信号  
  217.     kill(pid,SIGKILL);   //对子进程发送SIGKILL信号  
  218.     first_key=1;  
  219.   
  220. }  
  221.   
  222. /************************************************* 
  223. Function name: conti_play 
  224. Parameter    : pid_t 
  225. Description  : 继续函数 
  226. Return       : void 
  227. Argument     : void 
  228. **************************************************/  
  229. void conti_play(pid_t pid)  
  230. {  
  231.     printf("===============================CONTINUE=============================\n");  
  232.     kill(pid,SIGCONT); //对孙子进程发送SIGCONT信号  
  233.     play_flag=1;  
  234. }  
  235.   
  236. /************************************************* 
  237. Function name: next 
  238. Parameter    : pid_t 
  239. Description  : 下一首函数 
  240. Return       : void 
  241. Argument     : void 
  242. **************************************************/  
  243. void next(pid_t next_pid)  
  244. {  
  245.     struct song *nextsong;  
  246.   
  247.     printf("===============================NEXT MP3=============================\n");  
  248.     /*从共享内存获得孙子进程播放歌曲的节点指针*/  
  249.     memcpy(&nextsong,p_addr + sizeof(pid_t)+1,4);  
  250.     /*指向下首歌曲的节点*/  
  251.     nextsong = nextsong->next;  
  252.     /*杀死当前歌曲播放的子进程,孙子进程*/  
  253.     kill(pid,SIGKILL);  
  254.     kill(next_pid,SIGKILL);  
  255.     wait(NULL);  
  256.     startplay(&pid,nextsong);  
  257. }  
  258.   
  259. /************************************************* 
  260. Function name: prev 
  261. Parameter    : pid_t 
  262. Description  : 上一首函数 
  263. Return       : void 
  264. Argument     : void 
  265. **************************************************/  
  266. void prev(pid_t prev_pid)  
  267. {  
  268.     struct song *prevsong;  
  269.     /*从共享内存获得孙子进程播放歌曲的节点指针*/  
  270.     printf("===============================PRIOR MP3=============================\n");  
  271.     memcpy(&prevsong,p_addr + sizeof(pid_t)+1,4);  
  272.     /*指向上首歌曲的节点*/  
  273.     prevsong = prevsong->prev;  
  274.     /*杀死当前歌曲播放的子进程,孙子进程*/  
  275.     kill(pid,SIGKILL);  
  276.     kill(prev_pid,SIGKILL);  
  277.     wait(NULL);  
  278.     startplay(&pid,prevsong);  
  279. }  
  280.   
  281. /************************************************* 
  282. Function name: main 
  283. Parameter    : void 
  284. Description  : 主函数 
  285. Return       : int 
  286. Argument     : void 
  287. **************************************************/  
  288. int main(void)  
  289. {  
  290. //  int buttons_fd;  
  291.     int mp3_control_pipe;  
  292.     int mp3_control_pipe_write;  
  293. //  int key_value;  
  294.     int playnum;  
  295. //  char playnum;  
  296.     struct song *head;  
  297.     /*打开设备文件*/  
  298. //  buttons_fd = open("/dev/key", 0);  
  299. //  if (buttons_fd < 0) {  
  300. //      perror("open device buttons");  
  301. //      exit(1);  
  302. //  }  
  303.   
  304.    /*创建命名管道mp3-control*/  
  305.     unlink("/tmp/mp3_control");  
  306.     mkfifo("/tmp/mp3_control",0666);  
  307.       
  308.     mp3_control_pipe=open("/tmp/mp3_control",O_RDONLY|O_NONBLOCK);  
  309.     mp3_control_pipe_write=open("/tmp/mp3_control",O_WRONLY|O_NONBLOCK);  
  310.   
  311.   
  312.     if(mp3_control_pipe<0)  
  313.     {  
  314.        perror("open control pipe for read");    
  315.         }  
  316.   
  317.     printf("**********基于mini2440的网页控制MP3播放器*********** \n");  
  318.     printf("********************XXX制作 ************************ \n");  
  319.     printf("**************嵌入式开发项目************************ \n");  
  320.       
  321.   /*创建播放列表*/  
  322.     head = creat_song_list();  
  323.       
  324.     printf("===================================FUNTION======================================\n\n");  
  325.     printf("        K1:播放、暂停     K2:停止播放   K3:下一歌曲      K4:上一歌曲  \n\n");  
  326.     printf("================================================================================\n");  
  327.   
  328.   
  329.   /*共享内存:用于存放子进程ID,播放列表位置*/  
  330.     if((shmid = shmget(IPC_PRIVATE,5,PERM))== -1)  
  331.         exit(1);  
  332.     p_addr = shmat(shmid,0,0);  
  333.     memset(p_addr,'\0',1024);  
  334.       
  335.       
  336.     while(1)   
  337.     {  
  338.         fd_set rds;/*先声明一个 fd_set 集合来保存我们要检测的 buttons_fd句柄*/  
  339.         int ret1;  
  340.   
  341.         FD_ZERO(&rds);/*用select函数之前将rds清零*/  
  342.         FD_SET(mp3_control_pipe, &rds);/*将检测到的句柄放到集合rds里*/  
  343.   
  344.         /*监听获取键值*/  
  345.         //struct timeval timeout = {30,0};  
  346.         ret1 = select(mp3_control_pipe + 1, &rds, NULL, NULL,NULL);  
  347.         //printf ("%s %d %d\n", __FUNCTION__, __LINE__, ret1);  
  348.         if (ret1 < 0)   
  349.         {  
  350.             perror("select");  
  351.             exit(1);  
  352.         }  
  353.         if (ret1 == 0)   
  354.             printf("Timeout.\n");  
  355.         else if (FD_ISSET(mp3_control_pipe, &rds))  
  356.         {  
  357.             static char buffer[10];  
  358.             int ret = read(mp3_control_pipe, &buffer, 2);  
  359. //          printf ("%s %d %d\n", __FUNCTION__, __LINE__, ret);  
  360.             if (ret != 2)   
  361.             {  
  362.                 if (errno != EAGAIN) {  
  363.                     perror("read buttons\n");  
  364.                     continue;  
  365.                 }  
  366.             }   
  367.             else  
  368.             {     
  369.                 int playnum1;  
  370.                 if(sscanf(buffer,"%d",&playnum1)==1)  
  371.                     {  
  372.                      playnum=playnum1;  
  373.                     }  
  374.                 memset(buffer,0,sizeof(buffer));  
  375.   
  376.                 printf("buttons_value: %d\n", playnum);  
  377.                   
  378.                 /*首次播放,必须是按键1*/  
  379.                 if(first_key){  
  380.                     switch(playnum)  
  381.                     {     
  382.                     case 0:  
  383.                         startplay(&pid,head);  
  384.                         first_key=0;  
  385.                         break;  
  386.                     case 1:  
  387.                     case 2:  
  388.                     case 3:  
  389.                         printf("=======================PRESS K1 TO START PLAY===================\n");  
  390.                         break;  
  391.                     default:  
  392.                         printf("=======================PRESS K1 TO START PLAY===================\n");  
  393.                         break;  
  394.                     } //end switch  
  395.                 }//end if(first_key)  
  396.                 /*若不是首次播放,则根据不同键值处理*/  
  397.                 else if(!first_key){  
  398.                     switch(playnum)  
  399.                     {  
  400.                     case 0:  
  401.                         //printf("play_flag:%d\n",play_flag);  
  402.                         if(play_flag)  
  403.                             my_pause(gradchild);  
  404.                         else  
  405.                             conti_play(gradchild);  
  406.                         break;  
  407.                     case 1:  
  408.                         my_stop(gradchild);  
  409.                         break;  
  410.                     case 2:  
  411.                         next(gradchild);  
  412.                         break;  
  413.                     case 3:  
  414.                         prev(gradchild);  
  415.                         break;  
  416.                     } //end switch  
  417.              }//end if(!first_key)  
  418.   
  419.             }  
  420.                   
  421.         }  
  422.     }  
  423.     close(mp3_control_pipe);  
  424.     return 0;  
  425. }  


MP3播放的实现答题架构没有变,主要修改部分是控制部分,原来控制是由按键中断来实现的,现将其改为由进程间通信—— 命名管道 来控制,现将主要部分代码列出:

[cpp]  view plain  copy
  1. int main(void)  
  2. {  
  3.   
  4.     int mp3_control_pipe;  
  5.     int mp3_control_pipe_write;  
  6.     int playnum;  
  7.     struct song *head;  
  8.     /*打开设备文件*/  
  9.   
  10.     *创建命名管道mp3-control*/  
  11.     unlink("/tmp/mp3_control");  
  12.     mkfifo("/tmp/mp3_control",0666);  
  13.       
  14.     mp3_control_pipe=open("/tmp/mp3_control",O_RDONLY|O_NONBLOCK);  
  15.     mp3_control_pipe_write=open("/tmp/mp3_control",O_WRONLY|O_NONBLOCK);  
  16.   
  17.   
  18.     if(mp3_control_pipe<0)  
  19.     {  
  20.             perror("open control pipe for read");    
  21.     }  
这部分主要是建立一个命名管道mp3_control,以实现进程间通信,原来博主只是为了在MP3模块中不断的读取管道里面的数据,所以第一次时只是单独的读:

[cpp]  view plain  copy
  1. mp3_control_pipe=open("/tmp/mp3_control",O_RDONLY|O_NONBLOCK);  
但是后面执行时,却一直读取管道里面的内容,就是对一个相同的数据不断地读取,成了一个死循环,最后查找资料把写管道也打开了,这样才OK了,大家知道是什么原因吗?博主查找了相关资料,却没找到答案,只在某地看到这个,大家看看是什么意思,为什么要把读和写都打开


下面这段代码是不断的监听管道里面的数值,并作出相应操作

[cpp]  view plain  copy
  1.  /*共享内存:用于存放子进程ID,播放列表位置*/  
  2.     if((shmid = shmget(IPC_PRIVATE,5,PERM))== -1)  
  3.         exit(1);  
  4.     p_addr = shmat(shmid,0,0);  
  5.     memset(p_addr,'\0',1024);  
  6.       
  7.       
  8.     while(1)   
  9.     {  
  10.         fd_set rds;/*先声明一个 fd_set 集合来保存我们要检测的 buttons_fd句柄*/  
  11.         int ret1;  
  12.   
  13.         FD_ZERO(&rds);/*用select函数之前将rds清零*/  
  14.         FD_SET(mp3_control_pipe, &rds);/*将检测到的句柄放到集合rds里*/  
  15.   
  16.         /*监听获取键值*/  
  17.         //struct timeval timeout = {30,0};  
  18.         ret1 = select(mp3_control_pipe + 1, &rds, NULL, NULL,NULL);  
  19.         //printf ("%s %d %d\n", __FUNCTION__, __LINE__, ret1);  
  20.         if (ret1 < 0)   
  21.         {  
  22.             perror("select");  
  23.             exit(1);  
  24.         }  
  25.         if (ret1 == 0)   
  26.             printf("Timeout.\n");  
  27.         else if (FD_ISSET(mp3_control_pipe, &rds))  
  28.         {  
  29.             static char buffer[10];  
  30.             int ret = read(mp3_control_pipe, &buffer, 2);  
  31. //          printf ("%s %d %d\n", __FUNCTION__, __LINE__, ret);  
  32.             if (ret != 2)   
  33.             {  
  34.                 if (errno != EAGAIN) {  
  35.                     perror("read buttons\n");  
  36.                     continue;  
  37.                 }  
  38.             }   
  39.             else  
  40.             {     
  41.                 int playnum1;  
  42.                 if(sscanf(buffer,"%d",&playnum1)==1)  
  43.                     {  
  44.                      playnum=playnum1;  
  45.                     }  
  46.                 memset(buffer,0,sizeof(buffer));  
  47.   
  48.                 printf("buttons_value: %d\n", playnum);  

二、BOA服务器

BOA服务器这里先不详细介绍,主要通过调用CGI程序实现与应用程序的信息交互,这里就是调用CGI程序向管道里写数据的,代码如下:

[cpp]  view plain  copy
  1. #!/bin/sh  
  2.   
  3. type=0  
  4.   
  5.   
  6. case $QUERY_STRING in  
  7.     *play*)  
  8.         type=0  
  9.         ;;  
  10.     *stop*)  
  11.         type=1  
  12.         ;;  
  13.     *priv*)  
  14.         type=2  
  15.         ;;  
  16.     *next*)  
  17.         type=3  
  18.         ;;  
  19. esac  
  20.   
  21.   
  22.   
  23. /bin/echo $type > /tmp/mp3_control  
  24.   
  25. echo "Content-type: text/html; charset=gb2312"  
  26. echo  
  27. /bin/cat mp3-result.template  
  28.   
  29. exit 0  


这里是用shell脚本编写的,当然也可以用C来编写,具体BOA服务器和CGI博主打算单独写在一篇文章里。


三、WEB控制部分

  博主对WEB开发没有学习过,只是利用别人的脚本进行简单更改,代码如下:

[cpp]  view plain  copy
  1. <html xmlns="http://www.w3.org/1999/xhtml">  
  2. <head>  
  3. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />  
  4. <title>网页控制MP3</title>  
  5. <style type="text/css">  
  6. <!--  
  7. a:link {  color:#FFFFFF; text-decoration: none }  
  8. a:visited { color:#FFFFFF; text-decoration: none}  
  9. a:hover {  color: #FF6600; text-decoration: underline}  
  10. a.develop_item_link:link {color:#FF6600; font-size: 9pt; text-decoration:underline}  
  11. a.left_item_style:hover {color:green; font-size: 9pt; text-decoration:none}  
  12. a.develop_item_style:hover {color:"#00FF00"; font-size: 9pt; text-decoration:none}  
  13. a.download_item_style:hover {color:bule; font-size: 9pt; text-decoration:none}  
  14. a.middle_item_style:hover {color:red; font-size: 12pt; text-decoration:underline}  
  15. a.middle_item_style:link {  color: #000000; text-decoration: none}  
  16. a.middle_item_style:visited { color:#000000; text-decoration: none}  
  17. .STYLE13 {color:#FFFFFF; text-decoration: none}  
  18. .STYLE14 {  
  19.     font-size: 16px;  
  20.     font-weight: bold;  
  21. }  
  22.   
  23. -->  
  24. </style>  
  25.   
  26. <script language="JavaScript">  
  27. <!--  
  28.   
  29. var j,old_image;  
  30. function change_over(){  
  31.   var ob=change_over.arguments;  
  32.   for(i=0;i<document.all.length;i++)  
  33.   if(document.all[i].name==ob[0]) j=i;  
  34.   old_image=document.all[j].src;  
  35.   document.all[j].src=ob[1];  
  36. }   
  37.   
  38. function change_out(){  
  39.   document.all[j].src=old_image;  
  40. }  
  41. //-->  
  42. </script>  
  43. </head>  
  44.   
  45. <body bgcolor="#666666">  
  46. <table width="800" align="center" cellpadding="0">  
  47. <tr>  
  48.   <td width="9"> </td>  
  49.   <td width="781" colspan="2"><div align="center"><img src="images1/bar.jpg" width="780" height="120" /></div></td>  
  50. </tr>  
  51. <tr>  
  52.   <td> </td>  
  53.   <td colspan="2"><table width="780" cellpadding="0" cellspacing="0" border="0">  
  54.     <tr>  
  55.       <td> </td>  
  56.       <td> </td>  
  57.       <td> </td>  
  58.     </tr>  
  59.     <tr>  
  60.       <td width="250"><a href="mp3_control.html" onMouseOut="change_out()" onMouseOver="change_over('Image1','images1/bar_left_thick.jpg')"><img src="images1/bar_left_thick.jpg" width="780" height="37" border="0" name="Image1"></a></td>  
  61.         
  62.     </tr>  
  63.   </table></td>  
  64. </tr>  
  65. <tr>  
  66.   <td> </td>  
  67.   <td colspan="2"> </td>  
  68. </tr>  
  69. <tr>  
  70.   <td> </td>  
  71.   <td colspan="2"><form method="get" action="mp3_control.cgi" name="WEBCAM-TEST">  
  72.     <div align="center"><span class="STYLE9">点击下面的MP3播放选项,可以选择MP3播放 </span>  
  73.       </div>  
  74.   </form></td>  
  75. </tr>  
  76.   
  77.   
  78. <tr>  
  79.   <td> </td>  
  80.   <td colspan="2" align="center"><form method="get" action="mp3_control.cgi" name="LED-TEST">  
  81.   
  82.        <div align="left">  
  83.       <table border="0" width="280" align="center">  
  84.         <tr>  
  85.           <td width="133">  
  86.             <p align="center">选择播放</td>  
  87.              
  88.           </tr>  
  89.         <tr>  
  90.        </tr>  
  91.         <tr>  
  92.           <td width="140">  
  93.             <p align="center">  <input type="radio" value="play" checked name="type">播放/暂停</td>  
  94.             </tr>  
  95.             <tr>  
  96.                <td width="140">  
  97.                  <p align="center"><input type="radio" name="type" value="stop" checked>停止播放</td>  
  98.                  </tr>  
  99.                  <tr>       
  100.                      <td width="140">  
  101.                      <p align="center"> <input type="radio" name="type" value="priv">上一歌曲</td>  
  102.                      </tr>  
  103.                      <tr>  
  104.                          <td width="140">  
  105.                          <p align="center"><input type="radio" name="type" value="next">下一歌曲</td>  
  106.          
  107.             </tr>  
  108.   
  109.         <tr>  
  110.           <td colspan="2" width="272">  
  111.             <p align="center"><input type="submit" value="确定(OK)" name="submit"></td>  
  112.         </tr>  
  113.       </table>  
  114.      </div>  
  115.     <div align="center"></div><div align="center"></div><div align="left"></div><div align="left"></div></form> </td>  
  116. </tr>  
  117. <tr>  
  118.   <td height="42"> </td>  
  119.   <td colspan="2" background="images1/bottom.jpg" height="39" >  
  120.     <div align="center" class="STYLE13"> <strong>Web Server test page 肖志强制作</strong> <a href="http://embedclub.taobao.com/" class="STYLE14">17768137013 </a></div></td>  
  121. </tr>  
  122. <tr>  
  123.   <td> </td>  
  124.   <td colspan="2" align="center"> </td>  
  125. </tr>  
  126. </table>  
  127. </body>  
  128. </html>  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值