Skip to content

Commit 81e723f

Browse files
committed
*HomeMediaCenter*
Added support for streaming from Dreambox STB
1 parent 5824ac3 commit 81e723f

15 files changed

+346
-16
lines changed

HomeMediaCenter/HomeMediaCenter/HomeMediaCenter.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@
9999
<Reference Include="System.Xml" />
100100
</ItemGroup>
101101
<ItemGroup>
102+
<Compile Include="ItemContainerDreambox.cs" />
103+
<Compile Include="ItemContainerDreamboxRoot.cs" />
102104
<Compile Include="StreamSourcesBindingList.cs" />
103105
<Compile Include="BufferedAsyncStream.cs" />
104106
<Compile Include="ChunkedStream.cs" />

HomeMediaCenter/HomeMediaCenter/Item.cs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ namespace HomeMediaCenter
1919
[InheritanceMapping(Code = 7, Type = typeof(ItemStream))]
2020
[InheritanceMapping(Code = 8, Type = typeof(ItemContainerStreamRoot))]
2121
[InheritanceMapping(Code = 9, Type = typeof(ItemContainerStreamCustom))]
22+
[InheritanceMapping(Code = 10, Type = typeof(ItemContainerDreamboxRoot))]
23+
[InheritanceMapping(Code = 11, Type = typeof(ItemContainerDreambox))]
2224
public abstract class Item
2325
{
2426
public const string AudioIndex = "1";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Data.Linq;
6+
using System.Xml;
7+
using System.Net;
8+
9+
namespace HomeMediaCenter
10+
{
11+
public class ItemContainerDreambox : ItemContainerStream
12+
{
13+
protected class ServiceParamItemEqualityComparer : IEqualityComparer<object>
14+
{
15+
public new bool Equals(object x, object y)
16+
{
17+
ServiceParam itemX;
18+
Item itemY = y as Item;
19+
20+
if (itemY == null)
21+
{
22+
itemX = y as ServiceParam;
23+
itemY = x as Item;
24+
}
25+
else
26+
{
27+
itemX = x as ServiceParam;
28+
}
29+
30+
return (itemX.Title == itemY.Title) && (itemX.Path == itemY.Path);
31+
}
32+
33+
public int GetHashCode(object obj)
34+
{
35+
Item itemY = obj as Item;
36+
37+
if (itemY == null)
38+
{
39+
ServiceParam itemX = obj as ServiceParam;
40+
if (itemX == null)
41+
throw new NullReferenceException();
42+
43+
return itemX.Title.GetHashCode() ^ itemX.Path.GetHashCode();
44+
}
45+
else
46+
{
47+
return itemY.Title.GetHashCode() ^ itemY.Path.GetHashCode();
48+
}
49+
}
50+
}
51+
52+
protected class ServiceParam
53+
{
54+
public string Title
55+
{
56+
get; set;
57+
}
58+
59+
public string Path
60+
{
61+
get; set;
62+
}
63+
}
64+
65+
public ItemContainerDreambox() : base() { }
66+
67+
public ItemContainerDreambox(string title, string path, ItemContainer parent) : base(title, path, parent) { }
68+
69+
public override void RefreshMe(DataContext context, ItemManager manager, bool recursive)
70+
{
71+
if (manager.UpnpDevice.Stopping)
72+
return;
73+
74+
foreach (Item item in this.Items)
75+
item.RefreshMe(context, manager, true);
76+
}
77+
78+
public void RefreshDreambox(DataContext context, ItemManager manager, Uri basePath, bool isBouquet, ref string pathPrefix)
79+
{
80+
Uri servicePath = new Uri(basePath, "/web/getservices" + (isBouquet ? string.Empty : ("?sRef=" + this.Path)));
81+
82+
XmlDocument serviceDoc = new XmlDocument();
83+
serviceDoc.Load(servicePath.ToString());
84+
85+
string pPrefix;
86+
if (isBouquet)
87+
pPrefix = string.Empty;
88+
else if (pathPrefix == null)
89+
pPrefix = pathPrefix = GetDreamboxStreamAddress(basePath, serviceDoc);
90+
else
91+
pPrefix = pathPrefix;
92+
93+
94+
//Rozdielova obnova parametrov poloziek v tomto kontajnery
95+
IEnumerable<ServiceParam> serviceParams = serviceDoc.SelectNodes("/e2servicelist/e2service").Cast<XmlNode>().Select(
96+
a => new ServiceParam() { Title = a.SelectSingleNode("e2servicename").InnerText, Path = pPrefix + a.SelectSingleNode("e2servicereference").InnerText }
97+
).ToArray();
98+
99+
Item[] toRemove = this.Items.Except(serviceParams, new ServiceParamItemEqualityComparer()).Cast<Item>().ToArray();
100+
ServiceParam[] toAdd = serviceParams.Except(this.Items, new ServiceParamItemEqualityComparer()).Cast<ServiceParam>().ToArray();
101+
102+
RemoveRange(context, manager, toRemove);
103+
104+
foreach (ServiceParam param in toAdd)
105+
{
106+
if (isBouquet)
107+
new ItemContainerDreambox(param.Title, param.Path, this);
108+
else
109+
new ItemContainerStream(param.Title, param.Path, this);
110+
}
111+
}
112+
113+
private string GetDreamboxStreamAddress(Uri baseUri, XmlDocument serviceDoc)
114+
{
115+
try
116+
{
117+
//Pokusi sa ziskat stream port na zaklade prveho e2service
118+
string serviceRef = serviceDoc.SelectSingleNode("/e2servicelist/e2service/e2servicereference").InnerText;
119+
Uri playlistPath = new Uri(baseUri, "/web/stream.m3u?ref=" + serviceRef);
120+
121+
using (WebClient client = new WebClient())
122+
using (System.IO.Stream stream = client.OpenRead(playlistPath))
123+
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
124+
{
125+
string line;
126+
while ((line = reader.ReadLine()) != null)
127+
{
128+
if (!line.StartsWith("#"))
129+
break;
130+
}
131+
132+
Uri streamPath;
133+
if (Uri.TryCreate(line, UriKind.Absolute, out streamPath))
134+
return streamPath.GetLeftPart(UriPartial.Authority) + "/";
135+
}
136+
}
137+
catch { }
138+
139+
//Ak nie je najdeny odkaz nastav default port
140+
return string.Format("http://{0}:{1}/", baseUri.Host, 8001);
141+
}
142+
}
143+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Data.Linq;
6+
7+
namespace HomeMediaCenter
8+
{
9+
public class ItemContainerDreamboxRoot : ItemContainerDreambox
10+
{
11+
public ItemContainerDreamboxRoot() : base() { }
12+
13+
public ItemContainerDreamboxRoot(string title, string path, ItemContainer parent) : base(title, path, parent) { }
14+
15+
public override void RefreshMe(DataContext context, ItemManager manager, bool recursive)
16+
{
17+
if (manager.UpnpDevice.Stopping)
18+
return;
19+
20+
try
21+
{
22+
Uri url;
23+
if (!Uri.TryCreate(this.Path, UriKind.Absolute, out url))
24+
return;
25+
26+
//Obnoveie bouquets
27+
string bouquetsPrefix = null;
28+
RefreshDreambox(context, manager, url, true, ref bouquetsPrefix);
29+
30+
string servicesPrefix = null;
31+
foreach (ItemContainerDreambox item in this.Items.OfType<ItemContainerDreambox>())
32+
{
33+
//Obnovenie services v bouquet
34+
item.RefreshDreambox(context, manager, url, false, ref servicesPrefix);
35+
}
36+
37+
//Volanie obnovy do podadresarov - bez ohladu na premennu recursive - napr. treba obnovit aj nazvy
38+
foreach (Item item in this.Items)
39+
item.RefreshMe(context, manager, true);
40+
}
41+
catch { }
42+
}
43+
}
44+
}

HomeMediaCenter/HomeMediaCenter/ItemManager.cs

+20-10
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,14 @@ public List<StreamSourcesItem> GetStreamSources()
287287
using (SqlCeConnection conn = new SqlCeConnection(this.dbConnectionString))
288288
using (DataContext context = new DataContext(conn))
289289
{
290-
return context.GetTable<Item>().OfType<ItemContainerStreamCustom>().Select(delegate(ItemContainerStreamCustom a) {
291-
return new StreamSourcesItem(a.Id, a.Title, a.Path);
292-
}).ToList();
290+
ItemContainerStreamRoot root = context.GetTable<Item>().OfType<ItemContainerStreamRoot>().Single();
291+
292+
return root.Children.Where(
293+
a => a.GetType() == typeof(ItemContainerStreamCustom) || a.GetType() == typeof(ItemContainerDreamboxRoot)).Select(
294+
delegate(Item a) {
295+
return new StreamSourcesItem(a.Id, a.Title, a.Path,
296+
(a.GetType() == typeof(ItemContainerStreamCustom)) ? StreamSourcesItemType.Stream : StreamSourcesItemType.Dreambox);
297+
}).ToList();
293298
}
294299
}
295300
catch
@@ -313,32 +318,37 @@ public void SetStreamSources(StreamSourcesItem[] toAdd, StreamSourcesItem[] toUp
313318

314319
//Pridavanie zaznamov a odstranit nevyplnene polozky
315320
context.GetTable<Item>().InsertAllOnSubmit(
316-
toAdd.Where(a => !string.IsNullOrWhiteSpace(a.Title) && !string.IsNullOrWhiteSpace(a.Path)).Select(
317-
a => new ItemContainerStreamCustom(a.Title, a.Path, root)));
321+
toAdd.Where(a => !string.IsNullOrWhiteSpace(a.Title) && !string.IsNullOrWhiteSpace(a.Path)).Select(delegate(StreamSourcesItem a) {
322+
if (a.Type == StreamSourcesItemType.Stream)
323+
return (Item)(new ItemContainerStreamCustom(a.Title, a.Path, root));
324+
else
325+
return (Item)(new ItemContainerDreamboxRoot(a.Title, a.Path, root));
326+
}));
318327

319328
//Uprava existujucich zaznamov
320329
foreach (StreamSourcesItem item in toUpdate.Where(a => a.Id.HasValue))
321330
{
322-
ItemContainerStreamCustom updItem = root.Children.OfType<ItemContainerStreamCustom>().FirstOrDefault(a => a.Id == item.Id.Value);
331+
Item updItem = root.Children.FirstOrDefault(a => a.Id == item.Id.Value);
323332
if (updItem == null)
324333
continue;
325334

326335
if (item.Path != updItem.Path)
327336
updItem.Path = item.Path;
328337

329-
if (item.Title != updItem.Title)
338+
if (updItem.GetType() == typeof(ItemContainerStreamCustom) && item.Title != updItem.Title)
330339
{
331340
//Pre aktualizaciu nazvu je potrebne potomkov odstranit - pri refresh sa pridaju so spravnym nazvom
341+
//Plati iba pre ItemContainerStreamCustom
332342
updItem.RemoveMe(context, this);
333-
334-
updItem.Title = item.Title;
335343
}
344+
345+
updItem.Title = item.Title;
336346
}
337347

338348
//Mazanie zaznamov
339349
foreach (StreamSourcesItem item in toDelete.Where(a => a.Id.HasValue))
340350
{
341-
ItemContainerStreamCustom delItem = root.Children.OfType<ItemContainerStreamCustom>().FirstOrDefault(a => a.Id == item.Id.Value);
351+
Item delItem = root.Children.FirstOrDefault(a => a.Id == item.Id.Value);
342352
if (delItem == null)
343353
continue;
344354

HomeMediaCenter/HomeMediaCenter/LanguageResource.Designer.cs

+10-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

HomeMediaCenter/HomeMediaCenter/LanguageResource.resx

+3
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@
135135
<data name="Download" xml:space="preserve">
136136
<value>Download</value>
137137
</data>
138+
<data name="Dreambox" xml:space="preserve">
139+
<value>dreambox</value>
140+
</data>
138141
<data name="Duration" xml:space="preserve">
139142
<value>duration</value>
140143
</data>

HomeMediaCenter/HomeMediaCenter/StreamSourcesBindingList.cs

+14-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public class StreamSourcesBindingList : BindingList<StreamSourcesItem>
1111
private readonly Interfaces.IItemManager manager;
1212
private List<StreamSourcesItem> removedItems = new List<StreamSourcesItem>();
1313
private HashSet<StreamSourcesItem> updatedItems = new HashSet<StreamSourcesItem>();
14+
private StreamSourcesItemType actualType = StreamSourcesItemType.Stream;
1415

1516
public StreamSourcesBindingList() : base() { }
1617

@@ -20,6 +21,11 @@ public StreamSourcesBindingList(Interfaces.IItemManager manager)
2021
this.manager = manager;
2122
}
2223

24+
public StreamSourcesItemType ActualType
25+
{
26+
set { this.actualType = value; }
27+
}
28+
2329
public void SubmitChanges()
2430
{
2531
this.manager.SetStreamSources(
@@ -30,7 +36,14 @@ public void SubmitChanges()
3036

3137
protected override void OnListChanged(ListChangedEventArgs e)
3238
{
33-
if (e.ListChangedType == ListChangedType.ItemChanged)
39+
if (e.ListChangedType == ListChangedType.ItemAdded)
40+
{
41+
StreamSourcesItem item = this.Items[e.NewIndex];
42+
item.Type = this.actualType;
43+
if (this.actualType == StreamSourcesItemType.Dreambox)
44+
item.Path = "http://DREAMBOXIP:80";
45+
}
46+
else if (e.ListChangedType == ListChangedType.ItemChanged)
3447
{
3548
StreamSourcesItem item = this.Items[e.NewIndex];
3649
if (item.Id.HasValue)

0 commit comments

Comments
 (0)