Skip to content
This repository was archived by the owner on Jul 3, 2020. It is now read-only.

Commit fbca563

Browse files
author
matt
committed
User interface is a bit less awful after incremental improvement - still LOTS of room for improvement/redesign;
Tidied up some code in SSDP module and removed verbose logging; Changed MediaServerClient request to retireve all files, not just 30; Updated the main window to support video & image files;
1 parent e1ee34e commit fbca563

File tree

6 files changed

+119
-34
lines changed

6 files changed

+119
-34
lines changed

html/css/crdlna.css

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
html {
2+
overflow-y : scroll;
3+
}
4+
5+
body {
6+
display : flex;
7+
margin : 0;
8+
padding : 0;
9+
}
10+
/* Contains the list of devices we know about */
11+
#deviceList {
12+
border-right : 1px solid silver;
13+
width : 175px;
14+
overflow : auto;
15+
position : absolute;
16+
left : 0;
17+
top : 0;
18+
}
19+
20+
/* contains the content and playback section */
21+
#rightStack {
22+
display : flex;
23+
flex-direction : column;
24+
position : absolute;
25+
left : 176px;
26+
top : 0px;
27+
}
28+
29+
/* Container for individual content items (think folder listing ) */
30+
div.contentItems {
31+
background-color: #eee;
32+
display : flex;
33+
flex-direction : row;
34+
flex-wrap : wrap;
35+
width : 100%;
36+
}
37+
38+
/* Individual folder item */
39+
div.contentItem {
40+
background-color: white;
41+
border : 1px solid silver;
42+
border-radius : 3px;
43+
box-shadow : 0 0 0.6em #ccc;
44+
width : 64px;
45+
height : 64px;
46+
margin : 8px;
47+
padding : 4px;
48+
cursor : pointer;
49+
}
50+
51+
/* Individual folder item */
52+
div.contentItem:hover {
53+
box-shadow : 0 0 0.6em blue;
54+
}
55+

html/window.html

+19-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,30 @@
22
<html>
33
<head>
44
<title>Chrome DLNA Renderer</title>
5-
5+
<meta name="viewport" content="initial-scale=1">
6+
<link rel="stylesheet" href="css/crdlna.css" />
67
<script src="../scripts/ssdp/ssdp.js"></script>
78
<script src="../scripts/upnp/upnp.js"></script>
89
<script src="../scripts/upnp/MediaServerClient.js"></script>
910
<script src="../scripts/window/main.js"></script>
1011
</head>
1112
<body>
12-
Devices <a href="#" id="refreshDevices">Refresh</a>
13-
<div id="devices"></div>
13+
14+
<div id="deviceList">
15+
<a href="#" id="refreshDevices">Refresh</a>
16+
<div id="devices"></div>
17+
</div>
18+
19+
<div id="rightStack">
20+
<div id="content" class="contentItems">
21+
22+
</div>
23+
<div id="playback">
24+
25+
</div>
26+
</div>
27+
28+
29+
1430
</body>
1531
</html>

manifest.json

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
{
2121
"socket": ["udp-send-to", "udp-bind", "udp-multicast-membership"]
2222
},
23+
"webview",
2324
"http://*/" // Pretty wild but the UPnP discovery URL could be more or less anything
2425
],
2526
"icons": {"128": "images/logo-128.png" }

scripts/ssdp/ssdp.js

+15-16
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ SSDP.prototype.init = function(callback) {
4141
this.log("Initialising...");
4242

4343
var that = this;
44-
var cb = callback || function(){}
44+
var cb = callback || function(){};
4545

4646
chrome.sockets.udp.create({}, function (socket) {
4747
var socketId = socket.socketId;
4848
chrome.sockets.udp.onReceive.addListener(function(result) {
4949
var data = that.bufferToString(result.data);
5050
that.processNotify(data);
51-
})
51+
});
5252
// House keeping on TTL & loopback
5353
chrome.sockets.udp.setMulticastTimeToLive(socketId, 12, function (result) {
5454
if (result !== 0) {
@@ -63,15 +63,15 @@ SSDP.prototype.init = function(callback) {
6363

6464
function bind(port, cb) {
6565
chrome.sockets.udp.bind(socketId, that.address, port, function (result) {
66-
if(result === 0) return cb(result)
66+
if(result === 0) return cb(result);
6767
that.log('Unable to bind to new socket: ' + result + ", trying to bind to random port");
68-
chrome.sockets.udp.bind(socketId, that.address, 0, cb)
69-
})
68+
chrome.sockets.udp.bind(socketId, that.address, 0, cb);
69+
});
7070
}
7171
bind(that.port, function(result) {
7272
if(result !== 0) {
73-
that.log('Unable to bind to new socket: ' + result)
74-
return cb(result)
73+
that.log('Unable to bind to new socket: ' + result);
74+
return cb(result);
7575
}
7676
chrome.sockets.udp.joinGroup(socketId, that.multicast, function (result) {
7777
if (result !== 0) {
@@ -83,7 +83,7 @@ SSDP.prototype.init = function(callback) {
8383
}
8484
cb(result);
8585
});
86-
})
86+
});
8787

8888
});
8989
};
@@ -97,13 +97,13 @@ SSDP.prototype.sendDiscover = function(config) {
9797
var that = this;
9898
var c = config || {};
9999
var respondDelay = c.delay || 3;
100-
var target = c.target || 'ssdp:all'
100+
var target = c.target || 'ssdp:all';
101101

102102
var search = 'M-SEARCH * HTTP/1.1\r\n' +
103103
'HOST: 239.255.255.250:1900\r\n' +
104104
'MAN: "ssdp:discover"\r\n' +
105105
'MX: ' + respondDelay + '\r\n' +
106-
'ST: ' + target + '\r\n\r\n'
106+
'ST: ' + target + '\r\n\r\n';
107107

108108
var buffer = this.stringToBuffer(search);
109109
chrome.sockets.udp.send(this.socketId, buffer, that.multicast,
@@ -121,16 +121,15 @@ SSDP.prototype.sendDiscover = function(config) {
121121
SSDP.prototype.processNotify = function(str) {
122122
var notify = {};
123123

124-
str.replace(/([A-Z\-]*){1}:([^\n]*){1}/gi,
125-
function (match, m1, m2) {
124+
str.replace(/([A-Z\-]*){1}:([^\n]*){1}/gi, function (match, m1, m2) {
126125
var name = m1.toLowerCase().trim();
127126
name = name.replace('-',''); // remove any hypens, e.g. cache-control
128127
notify[name] = m2.trim();
129-
});
130-
if(!notify.usn)
131-
return;
128+
});
132129

133-
console.log('notify packet', notify)
130+
if(!notify.usn) {
131+
return;
132+
}
134133

135134
// Check for expiration/max-age
136135
if (notify.cachecontrol) {

scripts/upnp/MediaServerClient.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ MediaServerClient.prototype.browseFolder = function(folderId, callback) {
102102
'upnp:genre,upnp:author,upnp:actor,upnp:director,upnp:producer,upnp:publisher,' +
103103
'container@childCount,@childCount</Filter>' +
104104
'<StartingIndex>0</StartingIndex>' +
105-
'<RequestedCount>30</RequestedCount>' +
105+
'<RequestedCount>0</RequestedCount>' +
106106
'<SortCriteria/>' +
107107
'</u:Browse>' +
108108
'</s:Body>'+

scripts/window/main.js

+28-14
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ CrDlna.prototype.updateDeviceList = function () {
3636
}
3737
var container = document.createElement('div');
3838
var device = document.createElement('div');
39-
var listing = document.createElement('div');
39+
var listing = document.querySelector('#content')
4040
device.innerText = v.name;
4141
device.setAttribute('objectId', '0');
4242

@@ -65,36 +65,52 @@ CrDlna.prototype.updateDeviceList = function () {
6565
device.innerText += ' (not a media server)';
6666
}
6767
container.appendChild(device);
68-
container.appendChild(listing);
6968
list.appendChild(container);
7069
});
7170

7271
};
7372

7473
/**
75-
* Draws any child folders
74+
* Draws any child items
7675
*
7776
* @param {Object} elem The element into which to add the child items
7877
* @param {Object} data The object contianing the child folder data
7978
*/
8079
CrDlna.prototype.drawChildFolders = function (device, elem, data) {
81-
if (!data) return;
80+
if (!data || !elem) return;
8281

8382
var that = this;
84-
var list = document.createElement('ul');
83+
elem.innerHTML = '';
84+
85+
var playback = document.querySelector('#playback');
8586

8687
data.forEach(function (v, i, a){
87-
var child = document.createElement('li');
88+
var child = document.createElement('div');
89+
child.classList.add('contentItem');
8890
child.setAttribute('objectId', v.id);
8991
child.setAttribute('type', v.type);
90-
if (v.type.indexOf('object.item') >= 0) {
91-
// Item
92-
child.innerHTML = '<p>' + v.title + '</p><audio controls preload="none"><source src="' + v.url + '"></audio>';
92+
if (v.type.indexOf('videoItem') >= 0) {
93+
// Video Item
94+
child.innerHTML = '<p>' + v.title + '</p><video width="300" height="240" controls preload="none"><source src="' + v.url + '"></video>';
95+
96+
} else if (v.type.indexOf('imageItem') >= 0) {
97+
// Image Item
98+
child.innerHTML = '<p>' + v.title + '</p>';
99+
child.addEventListener('click', function() {
100+
playback.innerHTML = '<webview src="' + v.url + '" width="640" height="480" autosize="on"></webview>';
101+
});
102+
103+
} else if (v.type.indexOf('object.item') >= 0) {
104+
// Audio Item
105+
child.innerHTML = '<p>' + v.title + '</p>';
106+
child.addEventListener('click', function() {
107+
playback.innerHTML = '<audio controls autoplay><source src="' + v.url + '"></audio>';
108+
});
93109
} else {
94110
// Container
95-
111+
child.classList.add('contentFolder');
96112
child.innerText = v.title;
97-
child.addEventListener('click', function (){
113+
child.addEventListener('click', function () {
98114

99115
var sendBrowseRequest = new Promise(function(resolve, reject) {
100116
var client = that.clients[device.name];
@@ -114,11 +130,9 @@ CrDlna.prototype.drawChildFolders = function (device, elem, data) {
114130

115131
});
116132
}
117-
list.appendChild(child);
133+
elem.appendChild(child);
118134
});
119135

120-
elem.innerHTML = '';
121-
elem.appendChild(list);
122136
};
123137

124138
/**

0 commit comments

Comments
 (0)