├── README.md
├── config
└── 1.ini
├── default.aproj
├── dist
└── demo.jpg
├── form
└── about.aau
├── lib
└── web
│ └── layout
│ └── behavior
│ ├── about
│ └── link.aau
│ └── main
│ ├── button.aau
│ ├── channle.aau
│ ├── player.aau
│ └── playerControl.aau
├── main.aau
├── res
├── about.html
├── main.html
└── styles
│ ├── base.css
│ ├── images
│ ├── app.png
│ ├── live.png
│ ├── logo.jpg
│ ├── open.png
│ ├── pause.png
│ ├── play.png
│ ├── setting.png
│ └── volume.png
│ └── main.css
└── tv.ico
/README.md:
--------------------------------------------------------------------------------
1 | ## TV player
2 | A simple video player for http/ftp/mms/rtsp/rtmp/hls/m3u
3 |
4 | update:
5 | Jan,1 auto detect channel change
6 | Dec,20 add local file play support
7 |
8 | ## demo
9 | 
10 |
--------------------------------------------------------------------------------
/config/1.ini:
--------------------------------------------------------------------------------
1 | test1,http://dlhls.cdn.zhanqi.tv/zqlive/36799_8JBTz.m3u8
2 | test2,http://dlhls.cdn.zhanqi.tv/zqlive/46455_xR2MZ.m3u8
3 | mp4,http://127.0.0.1/test.mp4
4 | wmv,http://127.0.0.1/test.wmv
5 | mov,http://127.0.0.1/test.mov
6 | flv,http://127.0.0.1/test.flv
7 | rmvb,http://127.0.0.1/test.rmvb
8 | rtmp,rtmp://127.0.0.1/test
9 | mms,mms://127.0.0.1/test
10 | rstp,rstp://127.0.0.1/test
11 | ftp,ftp://127.0.0.1/test.rmvb
12 | hflv,http://127.0.0.1/test.hflv
13 | mkv,http://127.0.0.1/test.mkv
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/default.aproj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/default.aproj
--------------------------------------------------------------------------------
/dist/demo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/dist/demo.jpg
--------------------------------------------------------------------------------
/form/about.aau:
--------------------------------------------------------------------------------
1 | /*
2 | * tv
3 | * https://github.com/hikdo
4 | * January 1,2017
5 | */
6 |
7 | import win.ui;
8 | /*DSG{{*/
9 | var winform = ..win.form(text="TV";right=408;bottom=187;border="none")
10 | winform.add()
11 | /*}}*/
12 |
13 | import web.layout;
14 | import web.layout.behavior.windowCommand;
15 | import web.layout.behavior.windowSizer;
16 | import web.layout.behavior.about.link;
17 |
18 | var wbLayout = web.layout( winform )
19 | wbLayout.go("/res/about.html") ;
20 | import win.ui.shadow;
21 | win.ui.shadow(winform);
22 | winform.show()
23 | win.loopMessage();
24 | return winform;
25 |
--------------------------------------------------------------------------------
/lib/web/layout/behavior/about/link.aau:
--------------------------------------------------------------------------------
1 | /*
2 | * tv
3 | * https://github.com/hikdo
4 | * January 1,2017
5 | */
6 | namespace web.layout.behavior.about.link {
7 |
8 | onMouseClick = function( ltTarget,ltOwner,x,y,ltMouseParams ) {
9 |
10 | var link = ltOwner.getCustomAttribute("link");
11 | if(link) {
12 | import process;
13 | process.execute(link);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/web/layout/behavior/main/button.aau:
--------------------------------------------------------------------------------
1 | /*
2 | * tv
3 | * https://github.com/hikdo
4 | * January 1,2017
5 | */
6 | namespace web.layout.behavior.main.button{
7 |
8 | onMouseClick = {
9 |
10 | aboutBtn = function( ltTarget,ltOwner,x,y,ltMouseParams ) {
11 | var aboutForm = ..mainForm.loadForm("/form/about.aau");
12 | aboutForm.doModal(..mainForm.hwnd);
13 | }
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/lib/web/layout/behavior/main/channle.aau:
--------------------------------------------------------------------------------
1 | /*
2 | * tv
3 | * https://github.com/hikdo
4 | * January 1,2017
5 | */
6 | namespace web.layout.behavior.main.channle{
7 |
8 | var curChannel = null;
9 |
10 | onMouseClick = function( ltTarget,ltOwner,x,y,ltMouseParams ) {
11 |
12 | if(ltMouseParams.button_state == 1/*_HL_MAIN_MOUSE_BUTTON*/) {
13 | var link = ltOwner.getCustomAttribute("link");
14 | if(link) {
15 | if(..web.layout.behavior.main.player.aPlayer.getConfig(4) != link) {
16 | if(curChannel != null) {
17 | curChannel.setAttribute("selected","");
18 | }
19 | curChannel = ltOwner;
20 | ltOwner.setAttribute("selected","selected");
21 | ..web.layout.behavior.main.player.aPlayer.close();
22 | ..web.layout.behavior.main.player.aPlayer.open(link);
23 | }
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/web/layout/behavior/main/player.aau:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/lib/web/layout/behavior/main/player.aau
--------------------------------------------------------------------------------
/lib/web/layout/behavior/main/playerControl.aau:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/lib/web/layout/behavior/main/playerControl.aau
--------------------------------------------------------------------------------
/main.aau:
--------------------------------------------------------------------------------
1 | /*
2 | * tv
3 | * https://github.com/hikdo
4 | * January 1,2017
5 | */
6 |
7 | import win.ui;
8 | /*DSG{{*/
9 | mainForm = ..win.form(text="TV - live player";right=968;bottom=590;border="none")
10 | mainForm.add()
11 | /*}}*/
12 |
13 | import web.layout;
14 | import web.layout.behavior.windowCommand;
15 | import web.layout.behavior.main.player;
16 | import web.layout.behavior.main.channle;
17 | import web.layout.behavior.main.button;
18 | import web.layout.behavior.main.playerControl;
19 |
20 | wbLayout = web.layout( mainForm );
21 |
22 | if( _STUDIO_INVOKED ){
23 | import web.layout.debug;
24 | wbLayout.attachEventHandler( web.layout.debug );
25 | }
26 |
27 | import thread.event;
28 | import thread.command;
29 | import fsys.dirWatcher;
30 |
31 | thread.command.instance().updateChannel = function(){
32 | ..web.layout.behavior.main.player.init();
33 | }
34 |
35 | mainForm.watchThread = fsys.dirWatcher.thread(
36 | function(filename,action,actionText){
37 | import thread.command;
38 | thread.command.updateChannel();
39 | },"/config");
40 |
41 | mainForm.onClose = function(hwnd,message,wParam,lParam){
42 | if (!mainForm.watchThread) {
43 | return;
44 | }
45 | mainForm.watchThread.close();
46 | }
47 |
48 | wbLayout.go("/res/main.html");
49 |
50 | import win.ui.shadow;
51 | win.ui.shadow(mainForm);
52 |
53 | mainForm.show()
54 | return win.loopMessage();
55 |
--------------------------------------------------------------------------------
/res/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/res/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
25 |
26 |
27 |
32 |
33 |
00:00:00 / 00:00:00
34 |
35 |
36 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/res/styles/base.css:
--------------------------------------------------------------------------------
1 | html,body{
2 | margin:0;
3 | height:100%;
4 | background:#fff;
5 | overflow:hidden;
6 | }
7 | body[maximize]{
8 | border-radius:0;
9 | }
10 | body[maximize] #header{
11 | border-radius:0;
12 | }
13 | #header{
14 | height:30px;
15 | line-height:30px;
16 | background:rgb(123, 138, 148);
17 | cursor:default;
18 | behavior:windowCommand;
19 | overflow:hidden;
20 | }
21 | #header .title-bar{
22 | margin-right:95px;
23 | padding-left:5px;
24 | height:30px;
25 | font:system;
26 | color:#fff;
27 | }
28 | #header .title-bar .title {
29 | float:left;
30 | margin-left:8px;
31 | display:inline-block;
32 | }
33 | #header .titlebox{
34 | width:max-intrinsic;
35 | height:30px;
36 | float:right;
37 | margin:0;
38 | overflow-x:hidden;
39 | }
40 | #header .titlebox a{
41 | display:inline-block;
42 | width:max-intrinsic;
43 | height:30px;
44 | font-family:"Marlett";
45 | font-size:14px;
46 | padding:0px 4px;
47 | color:#fff;
48 | cursor:default;
49 | }
50 | #header .titlebox a[command]:hover{
51 | background:#6ebccf;
52 | }
53 | #header a[command="window-restore"]{
54 | content:"2";
55 | }
56 | #header i.logo {
57 | float:left;
58 | display:inline-block;
59 | margin-top:4px;
60 | width:24px;
61 | height:24px;
62 | background:url(images/app.png);
63 | }
64 | #container{
65 | width:100%;
66 | height:100%%;
67 | flow: horizontal;
68 | margin:0 auto;
69 | overflow:hidden;
70 | }
--------------------------------------------------------------------------------
/res/styles/images/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/app.png
--------------------------------------------------------------------------------
/res/styles/images/live.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/live.png
--------------------------------------------------------------------------------
/res/styles/images/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/logo.jpg
--------------------------------------------------------------------------------
/res/styles/images/open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/open.png
--------------------------------------------------------------------------------
/res/styles/images/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/pause.png
--------------------------------------------------------------------------------
/res/styles/images/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/play.png
--------------------------------------------------------------------------------
/res/styles/images/setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/setting.png
--------------------------------------------------------------------------------
/res/styles/images/volume.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/res/styles/images/volume.png
--------------------------------------------------------------------------------
/res/styles/main.css:
--------------------------------------------------------------------------------
1 | @set tv_scrollbar {
2 | .base { width: 2px; }
3 | :root { background-color: #0E0E0E; }
4 | :root:hover { }
5 | .base, .prev, .next, .next-page, .prev-page {
6 | background-color: transparent; border: none;
7 | }
8 | .slider {
9 | height:15px;
10 | background: #000;
11 | }
12 | .slider:hover {
13 | /*background: #333;*/
14 | }
15 | }
16 | #aboutBtn {
17 | behavior:~ "main.button";
18 | }
19 | #channleList {
20 | width:200px;
21 | height:100%%;
22 | background:#0E0E0E;
23 | overflow:auto; vertical-scrollbar: tv_scrollbar;
24 | padding:15px 0;
25 | }
26 | #channleList:hover {
27 | assigned!: self:focus = true;
28 | }
29 | #player {height:100%%;background:#000000;padding:5px;}
30 | #playerWidget { background:#000000;}
31 | #channelListUl {margin:0;padding:0;}
32 | #channelListUl li {
33 | list-style:none;
34 | display:block;
35 | width:100%%;
36 | height:30px;
37 | line-height:30px;
38 | color:#FFF;
39 | font-size:12px;
40 | cursor:pointer;
41 | padding-left:10px;
42 | behavior:~url(main.channle);
43 | }
44 | #channelListUl li a {
45 | display:block;
46 | width:100%%;
47 | cursor:pointer;
48 | padding-left:23px;
49 | foreground:url(/res/styles/images/live.png) no-repeat left center;
50 | }
51 | #channelListUl li:hover {
52 | color:#B70031;
53 | background:#000000;
54 | opacity:0.9;
55 | }
56 | #channelListUl li[selected=selected]{
57 | color:#B70031;
58 | background:#000000;
59 | opacity:0.9;
60 | }
61 | #controls {
62 | height:30px;
63 | width:100%%;
64 | background: #333;
65 | display:table;
66 | padding:0px 15px;
67 | }
68 | #ctrl-wrap {
69 | width:100%%;height:100%%;
70 | display:table-cell;vertical-align:middle;
71 | flow:horizontal;
72 | }
73 | #ctrl-left,#ctrl-right {
74 | flow:horizontal;
75 | width:120px;
76 | }
77 | #ctrl-left {text-align:left;}
78 | #ctrl-center {
79 | width:100%%;
80 | flow:horizontal;
81 | padding:0 30px 0 10px;
82 | }
83 | .ctrl-btn {height: 16px; width:16px;margin-right:25px; cursor:pointer; overflow: hidden; behavior:~url(main.playerControl);}
84 | #ctrlChannel {background: url(/res/styles/images/setting.png);}
85 | #ctrlOpen {background: url(/res/styles/images/open.png);}
86 | #ctrlPlay {background: url(/res/styles/images/play.png);}
87 | #ctrlMute {width:19px; height: 23px; background: url(/res/styles/images/volume.png); behavior:~url(main.playerControl);}
88 | #ctrlVolume {margin-top:5px;behavior:~url(main.playerControl);}
89 | #ctrlVolume img {display: none; width:7px; height:11px; overflow:hidden;}
90 | #ctrlVolume img {display: block; background-image: none;background-color: #f26c4f; foreground-image: none; }
91 | #ctrlProgress {margin-top:8px;width:100%%;behavior:~url(main.playerControl);}
92 | #ctrlProgress img {width:7px; height:11px;display: block; background-image: none;background-color: #f26c4f; foreground-image: none; }
93 | #timeshow {width:150px;line-height: 30px;color:#FFF;font-size:12px;}
--------------------------------------------------------------------------------
/tv.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yikza/tv/5e209d0e33072ad080f1110a39453b9482f10a85/tv.ico
--------------------------------------------------------------------------------