public void add(HTSMessage message) { _tunerDataHelper.addTunerInfo(message); lock (_data) { if (_data.ContainsKey(message.getInt("channelId"))) { int channelID = message.getInt("channelId"); HTSMessage storedMessage = _data[channelID]; if (storedMessage != null) { foreach (KeyValuePair<string, object> entry in message) { if (storedMessage.containsField(entry.Key)) { storedMessage.removeField(entry.Key); } storedMessage.putField(entry.Key, entry.Value); } } else { _logger.Error("[TVHclient] ChannelDataHelper: update for channelID '" + channelID + "' but no initial data found!"); } } else { if (message.containsField("channelNumber") && message.getInt("channelNumber") > 0) // use only channels with number > 0 { _data.Add(message.getInt("channelId"), message); } } } }
public void dvrEntryDelete(HTSMessage message) { string id = message.getString("id"); lock (_data) { _data.Remove(id); } }
public void addTunerInfo(HTSMessage tunerMessage) { lock(_data) { string channelID = "" + tunerMessage.getInt("channelId"); if (_data.ContainsKey(channelID)) { _data.Remove(channelID); } _data.Add(channelID, tunerMessage); } }
public void dvrEntryAdd(HTSMessage message) { string id = message.getString("id"); lock (_data) { if (_data.ContainsKey(id)) { _logger.Info("[TVHclient] DvrDataHelper.dvrEntryAdd id already in database - skip!" + message.ToString()); return; } _data.Add(id, message); } }
public void dvrEntryUpdate(HTSMessage message) { string id = message.getString("id"); lock (_data) { HTSMessage oldMessage = _data[id]; if (oldMessage == null) { _logger.Info("[TVHclient] DvrDataHelper.dvrEntryUpdate id not in database - skip!" + message.ToString()); return; } foreach (KeyValuePair<string, object> entry in message) { if (oldMessage.containsField(entry.Key)) { oldMessage.removeField(entry.Key); } oldMessage.putField(entry.Key, entry.Value); } } }
private void SendingHandler() { Boolean threadOk = true; while (_connected && threadOk) { if (_sendingHandlerThreadTokenSource.IsCancellationRequested) { return; } try { HTSMessage message = _messagesForSendQueue.Dequeue(); byte[] data2send = message.BuildBytes(); int bytesSent = _socket.Send(data2send); if (bytesSent != data2send.Length) { _logger.LogError("[TVHclient] SendingHandler: Sending not complete! \nBytes sent: {txbytes}\nMessage bytes: " + "{msgbytes}\nMessage: {msg}", bytesSent, data2send.Length, message.ToString()); } } catch (Exception ex) { threadOk = false; _logger.LogError(ex, "[TVHclient] SendingHandler caught exception"); if (_listener != null) { _listener.onError(ex); } else { _logger.LogError(ex, "[TVHclient] SendingHandler caught exception, but no error listener is configured!!!"); } } } }
public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken) { ensureConnection(); int timeOut = await WaitForInitialLoadTask(cancellationToken); if (timeOut == -1 || cancellationToken.IsCancellationRequested) { _logger.Info("[TVHclient] GetProgramsAsync, call canceled or timed out - returning empty list."); return new List<ProgramInfo>(); } GetEventsResponseHandler currGetEventsResponseHandler = new GetEventsResponseHandler(startDateUtc, endDateUtc, _logger, cancellationToken); HTSMessage queryEvents = new HTSMessage(); queryEvents.Method = "getEvents"; queryEvents.putField("channelId", Convert.ToInt32(channelId)); _htsConnection.sendMessage(queryEvents, currGetEventsResponseHandler); //IEnumerable<ProgramInfo> pi = await currGetEventsResponseHandler.GetEvents(cancellationToken); //return pi; TaskWithTimeoutRunner<IEnumerable<ProgramInfo>> twtr = new TaskWithTimeoutRunner<IEnumerable<ProgramInfo>>(TIMEOUT); TaskWithTimeoutResult<IEnumerable<ProgramInfo>> twtRes = await twtr.RunWithTimeout(currGetEventsResponseHandler.GetEvents(cancellationToken)); if (twtRes.HasTimeout) { return new List<ProgramInfo>(); } return twtRes.Result; }
public void handleResponse(HTSMessage response) { _responseDataQueue.Enqueue(response); }
public async Task<MediaSourceInfo> GetRecordingStream(string recordingId, string mediaSourceId, CancellationToken cancellationToken) { HTSMessage getTicketMessage = new HTSMessage(); getTicketMessage.Method = "getTicket"; getTicketMessage.putField("dvrId", recordingId); TaskWithTimeoutRunner<HTSMessage> twtr = new TaskWithTimeoutRunner<HTSMessage>(TIMEOUT); TaskWithTimeoutResult<HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew<HTSMessage>(() => { LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); _htsConnectionHandler.SendMessage(getTicketMessage, lbrh); return lbrh.getResponse(); })); if (twtRes.HasTimeout) { _logger.Error("[TVHclient] Timeout obtaining playback authentication ticket from TVH"); } else { HTSMessage getTicketResponse = twtRes.Result; if (_subscriptionId == int.MaxValue) { _subscriptionId = 0; } int currSubscriptionId = _subscriptionId++; if (_htsConnectionHandler.GetEnableSubsMaudios()) { _logger.Info("[TVHclient] Support for live TV subtitles and multiple audio tracks is enabled."); MediaSourceInfo recordingasset = new MediaSourceInfo(); recordingasset.Id = "" + currSubscriptionId; // Use HTTP basic auth instead of TVH ticketing system for authentication to allow the users to switch subs or audio tracks at any time recordingasset.Path = _htsConnectionHandler.GetHttpBaseUrl() + getTicketResponse.getString("path"); recordingasset.Protocol = MediaProtocol.Http; // Set asset source and type for stream probing and logging string recordingasset_probeUrl = "" + recordingasset.Path; string recordingasset_source = "Recording"; // Probe the asset stream to determine available sub-streams await ProbeStream(recordingasset, recordingasset_probeUrl, recordingasset_source, cancellationToken); // If enabled, force video deinterlacing for recordings if (_htsConnectionHandler.GetForceDeinterlace()) { _logger.Info("[TVHclient] Force video deinterlacing for all channels and recordings is enabled."); foreach (MediaStream i in recordingasset.MediaStreams) { if (i.Type == MediaStreamType.Video && i.IsInterlaced == false) { i.IsInterlaced = true; } } } return recordingasset; } else { return new MediaSourceInfo { Id = "" + currSubscriptionId, Path = _htsConnectionHandler.GetHttpBaseUrl() + getTicketResponse.getString("path") + "?ticket=" + getTicketResponse.getString("ticket"), Protocol = MediaProtocol.Http, MediaStreams = new List<MediaStream> { new MediaStream { Type = MediaStreamType.Video, // Set the index to -1 because we don't know the exact index of the video stream within the container Index = -1, // Set to true if unknown to enable deinterlacing IsInterlaced = true }, new MediaStream { Type = MediaStreamType.Audio, // Set the index to -1 because we don't know the exact index of the audio stream within the container Index = -1 } } }; } } throw new TimeoutException(); }
public Boolean authenticate(String username, String password) { _logger.LogDebug("[TVHclient] HTSConnectionAsync.authenticate: start"); HTSMessage helloMessage = new HTSMessage(); helloMessage.Method = "hello"; helloMessage.putField("clientname", _clientName); helloMessage.putField("clientversion", _clientVersion); helloMessage.putField("htspversion", HTSMessage.HTSP_VERSION); helloMessage.putField("username", username); LoopBackResponseHandler loopBackResponseHandler = new LoopBackResponseHandler(); sendMessage(helloMessage, loopBackResponseHandler); HTSMessage helloResponse = loopBackResponseHandler.getResponse(); if (helloResponse != null) { if (helloResponse.containsField("htspversion")) { _serverProtocolVersion = helloResponse.getInt("htspversion"); } else { _serverProtocolVersion = -1; _logger.LogDebug("[TVHclient] HTSConnectionAsync.authenticate: hello didn't include required field 'htspversion' - htsp incorrectly implemented by tvheadend"); } if (helloResponse.containsField("servername")) { _servername = helloResponse.getString("servername"); } else { _servername = "n/a"; _logger.LogDebug("[TVHclient] HTSConnectionAsync.authenticate: hello didn't include required field 'servername' - htsp incorrectly implemented by tvheadend"); } if (helloResponse.containsField("serverversion")) { _serverversion = helloResponse.getString("serverversion"); } else { _serverversion = "n/a"; _logger.LogDebug("[TVHclient] HTSConnectionAsync.authenticate: hello didn't include required field 'serverversion' - htsp incorrectly implemented by tvheadend"); } byte[] salt = null; if (helloResponse.containsField("challenge")) { salt = helloResponse.getByteArray("challenge"); } else { salt = new byte[0]; _logger.LogInformation("[TVHclient] HTSConnectionAsync.authenticate: hello didn't include required field 'challenge' - htsp incorrectly implemented by tvheadend"); } byte[] digest = SHA1helper.GenerateSaltedSHA1(password, salt); HTSMessage authMessage = new HTSMessage(); authMessage.Method = "authenticate"; authMessage.putField("username", username); authMessage.putField("digest", digest); sendMessage(authMessage, loopBackResponseHandler); HTSMessage authResponse = loopBackResponseHandler.getResponse(); if (authResponse != null) { Boolean auth = authResponse.getInt("noaccess", 0) != 1; if (auth) { HTSMessage getDiskSpaceMessage = new HTSMessage(); getDiskSpaceMessage.Method = "getDiskSpace"; sendMessage(getDiskSpaceMessage, loopBackResponseHandler); HTSMessage diskSpaceResponse = loopBackResponseHandler.getResponse(); if (diskSpaceResponse != null) { long freeDiskSpace = -1; long totalDiskSpace = -1; if (diskSpaceResponse.containsField("freediskspace")) { freeDiskSpace = diskSpaceResponse.getLong("freediskspace") / BytesPerGiga; } else { _logger.LogDebug("[TVHclient] HTSConnectionAsync.authenticate: getDiskSpace didn't include required field 'freediskspace' - htsp incorrectly implemented by tvheadend"); } if (diskSpaceResponse.containsField("totaldiskspace")) { totalDiskSpace = diskSpaceResponse.getLong("totaldiskspace") / BytesPerGiga; } else { _logger.LogDebug("[TVHclient] HTSConnectionAsync.authenticate: getDiskSpace didn't include required field 'totaldiskspace' - htsp incorrectly implemented by tvheadend"); } _diskSpace = freeDiskSpace + "GB / " + totalDiskSpace + "GB"; } HTSMessage enableAsyncMetadataMessage = new HTSMessage(); enableAsyncMetadataMessage.Method = "enableAsyncMetadata"; sendMessage(enableAsyncMetadataMessage, null); } _logger.LogDebug("[TVHclient] HTSConnectionAsync.authenticate: authenticated = {m}", auth); return(auth); } } _logger.LogError("[TVHclient] HTSConnectionAsync.authenticate: no hello response"); return(false); }
public Boolean authenticate(String username, String password) { _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: start"); HTSMessage helloMessage = new HTSMessage(); helloMessage.Method = "hello"; helloMessage.putField("clientname", _clientName); helloMessage.putField("clientversion", _clientVersion); helloMessage.putField("htspversion", HTSMessage.HTSP_VERSION); helloMessage.putField("username", username); LoopBackResponseHandler loopBackResponseHandler = new LoopBackResponseHandler(); sendMessage(helloMessage, loopBackResponseHandler); HTSMessage helloResponse = loopBackResponseHandler.getResponse(); if (helloResponse != null) { if (helloResponse.containsField("htspversion")) { _serverProtocolVersion = helloResponse.getInt("htspversion"); } else { _serverProtocolVersion = -1; _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'htspversion' - htsp wrong implemented on tvheadend side."); } if (helloResponse.containsField("servername")) { _servername = helloResponse.getString("servername"); } else { _servername = "n/a"; _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'servername' - htsp wrong implemented on tvheadend side."); } if (helloResponse.containsField("serverversion")) { _serverversion = helloResponse.getString("serverversion"); } else { _serverversion = "n/a"; _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'serverversion' - htsp wrong implemented on tvheadend side."); } byte[] salt = null; if (helloResponse.containsField("challenge")) { salt = helloResponse.getByteArray("challenge"); } else { salt = new byte[0]; _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: hello don't deliver required field 'challenge' - htsp wrong implemented on tvheadend side."); } byte[] digest = SHA1helper.GenerateSaltedSHA1(password, salt); HTSMessage authMessage = new HTSMessage(); authMessage.Method = "authenticate"; authMessage.putField("username", username); authMessage.putField("digest", digest); sendMessage(authMessage, loopBackResponseHandler); HTSMessage authResponse = loopBackResponseHandler.getResponse(); if (authResponse != null) { Boolean auth = authResponse.getInt("noaccess", 0) != 1; if (auth) { HTSMessage getDiskSpaceMessage = new HTSMessage(); getDiskSpaceMessage.Method = "getDiskSpace"; sendMessage(getDiskSpaceMessage, loopBackResponseHandler); HTSMessage diskSpaceResponse = loopBackResponseHandler.getResponse(); if (diskSpaceResponse != null) { long freeDiskSpace = -1; long totalDiskSpace = -1; if (diskSpaceResponse.containsField("freediskspace")) { freeDiskSpace = diskSpaceResponse.getLong("freediskspace") / BytesPerGiga; } else { _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: getDiskSpace don't deliver required field 'freediskspace' - htsp wrong implemented on tvheadend side."); } if (diskSpaceResponse.containsField("totaldiskspace")) { totalDiskSpace = diskSpaceResponse.getLong("totaldiskspace") / BytesPerGiga; } else { _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: getDiskSpace don't deliver required field 'totaldiskspace' - htsp wrong implemented on tvheadend side."); } _diskSpace = freeDiskSpace + "GB / " + totalDiskSpace + "GB"; } HTSMessage enableAsyncMetadataMessage = new HTSMessage(); enableAsyncMetadataMessage.Method = "enableAsyncMetadata"; sendMessage(enableAsyncMetadataMessage, null); } _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: authenticated = " + auth); return auth; } } _logger.Error("[TVHclient] HTSConnectionAsync.authenticate: no hello response"); return false; }
private static HTSMessage deserializeBinary(byte[] messageData) { byte type, namelen; long datalen; HTSMessage msg = new HTSMessage(); int cnt = 0; ByteBuffer buf = new ByteBuffer(messageData); while (buf.hasRemaining()) { type = buf.get(); namelen = buf.get(); datalen = uIntToLong(buf.get(), buf.get(), buf.get(), buf.get()); if (buf.Length() < namelen + datalen) { throw new IOException("Buffer limit exceeded"); } //Get the key for the map (the name) string name = null; if (namelen == 0) { name = Convert.ToString(cnt++); } else { byte[] bName = new byte[namelen]; buf.get(bName); name = NewString(bName); } //Get the actual content object obj = null; byte[] bData = new byte[datalen]; buf.get(bData); switch (type) { case HTSMessage.HMF_STR: { obj = NewString(bData); break; } case HMF_BIN: { obj = bData; break; } case HMF_S64: { obj = toBigInteger(bData); break; } case HMF_MAP: { obj = deserializeBinary(bData); break; } case HMF_LIST: { obj = new List <object>(deserializeBinary(bData)._dict.Values); break; } default: throw new IOException("Unknown data type"); } msg.putField(name, obj); } return(msg); }
private static HTSMessage deserializeBinary(byte[] messageData) { byte type, namelen; long datalen; HTSMessage msg = new HTSMessage(); int cnt = 0; ByteBuffer buf = new ByteBuffer(messageData); while (buf.hasRemaining()) { type = buf.get(); namelen = buf.get(); datalen = uIntToLong(buf.get(), buf.get(), buf.get(), buf.get()); if (buf.Length() < namelen + datalen) { throw new IOException("Buffer limit exceeded"); } //Get the key for the map (the name) string name = null; if (namelen == 0) { name = Convert.ToString(cnt++); } else { byte[] bName = new byte[namelen]; buf.get(bName); name = NewString(bName); } //Get the actual content object obj = null; byte[] bData = new byte[datalen]; buf.get(bData); switch (type) { case HTSMessage.HMF_STR: { obj = NewString(bData); break; } case HMF_BIN: { obj = bData; break; } case HMF_S64: { obj = toBigInteger(bData); break; } case HMF_MAP: { obj = deserializeBinary(bData); break; } case HMF_LIST: { obj = new List<object>(deserializeBinary(bData)._dict.Values); break; } default: throw new IOException("Unknown data type"); } msg.putField(name, obj); } return msg; }
public void SendMessage(HTSMessage message, HTSResponseHandler responseHandler) { _htsConnection.sendMessage(message, responseHandler); }
public void onMessage(HTSMessage response) { if (response != null) { switch (response.Method) { case "tagAdd": case "tagUpdate": case "tagDelete": //_logger.Fatal("[TVHclient] tad add/update/delete" + response.ToString()); break; case "channelAdd": case "channelUpdate": _channelDataHelper.Add(response); break; case "dvrEntryAdd": _dvrDataHelper.dvrEntryAdd(response); break; case "dvrEntryUpdate": _dvrDataHelper.dvrEntryUpdate(response); break; case "dvrEntryDelete": _dvrDataHelper.dvrEntryDelete(response); break; case "autorecEntryAdd": _autorecDataHelper.autorecEntryAdd(response); break; case "autorecEntryUpdate": _autorecDataHelper.autorecEntryUpdate(response); break; case "autorecEntryDelete": _autorecDataHelper.autorecEntryDelete(response); break; case "eventAdd": case "eventUpdate": case "eventDelete": // should not happen as we don't subscribe for this events. break; //case "subscriptionStart": //case "subscriptionGrace": //case "subscriptionStop": //case "subscriptionSkip": //case "subscriptionSpeed": //case "subscriptionStatus": // _logger.Fatal("[TVHclient] subscription events " + response.ToString()); // break; //case "queueStatus": // _logger.Fatal("[TVHclient] queueStatus event " + response.ToString()); // break; //case "signalStatus": // _logger.Fatal("[TVHclient] signalStatus event " + response.ToString()); // break; //case "timeshiftStatus": // _logger.Fatal("[TVHclient] timeshiftStatus event " + response.ToString()); // break; //case "muxpkt": // streaming data // _logger.Fatal("[TVHclient] muxpkt event " + response.ToString()); // break; case "initialSyncCompleted": _initialLoadFinished = true; break; default: //_logger.Fatal("[TVHclient] Method '" + response.Method + "' not handled in LiveTvService.cs"); break; } } }
public Boolean authenticate(String username, String password) { _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: start"); HTSMessage helloMessage = new HTSMessage(); helloMessage.Method = "hello"; helloMessage.putField("clientname", _clientName); helloMessage.putField("clientversion", _clientVersion); helloMessage.putField("htspversion", HTSMessage.HTSP_VERSION); helloMessage.putField("username", username); LoopBackResponseHandler loopBackResponseHandler = new LoopBackResponseHandler(); sendMessage(helloMessage, loopBackResponseHandler); HTSMessage helloResponse = loopBackResponseHandler.getResponse(); if (helloResponse != null) { _serverProtocolVersion = helloResponse.getInt("htspversion"); _servername = helloResponse.getString("servername"); _serverversion = helloResponse.getString("serverversion"); byte[] salt = helloResponse.getByteArray("challenge"); byte[] digest = SHA1helper.GenerateSaltedSHA1(password, salt); HTSMessage authMessage = new HTSMessage(); authMessage.Method = "authenticate"; authMessage.putField("username", username); authMessage.putField("digest", digest); sendMessage(authMessage, loopBackResponseHandler); HTSMessage authResponse = loopBackResponseHandler.getResponse(); if (authResponse != null) { Boolean auth = authResponse.getInt("noaccess", 0) != 1; if (auth) { HTSMessage getDiskSpaceMessage = new HTSMessage(); getDiskSpaceMessage.Method = "getDiskSpace"; sendMessage(getDiskSpaceMessage, loopBackResponseHandler); HTSMessage diskSpaceResponse = loopBackResponseHandler.getResponse(); if (diskSpaceResponse != null) { _diskSpace = (diskSpaceResponse.getLong("freediskspace") / BytesPerGiga) + "GB / " + (diskSpaceResponse.getLong("totaldiskspace") / BytesPerGiga) + "GB"; } HTSMessage enableAsyncMetadataMessage = new HTSMessage(); enableAsyncMetadataMessage.Method = "enableAsyncMetadata"; sendMessage(enableAsyncMetadataMessage, null); } _logger.Info("[TVHclient] HTSConnectionAsync.authenticate: authenticated = " + auth); return auth; } } _logger.Error("[TVHclient] HTSConnectionAsync.authenticate: no hello response"); return false; }
public void handleResponse(HTSMessage response) { _logger.Info("[TVHclient] GetEventsResponseHandler.handleResponse: received answer from TVH server\n" + response.ToString()); if (response.containsField("events")) { IList events = response.getList("events"); foreach (HTSMessage currEventMessage in events) { ProgramInfo pi = new ProgramInfo(); if (currEventMessage.containsField("start")) { long currStartTimeUnix = currEventMessage.getLong("start"); DateTime currentStartDateTimeUTC = _initialDateTimeUTC.AddSeconds(currStartTimeUnix).ToUniversalTime(); int compResult = DateTime.Compare(currentStartDateTimeUTC, _endDateTimeUtc); if (compResult > 0) { _logger.Info("[TVHclient] GetEventsResponseHandler.handleResponse: start value of event larger query stop value - skipping! \n" + "Query start UTC dateTime: " + _startDateTimeUtc + "\n" + "Query end UTC dateTime: " + _endDateTimeUtc + "\n" + "Event start UTC dateTime: " + currentStartDateTimeUTC + "\n" + currEventMessage.ToString()); continue; } pi.StartDate = currentStartDateTimeUTC; } else { _logger.Info("[TVHclient] GetEventsResponseHandler.handleResponse: no start value for event - skipping! \n" + currEventMessage.ToString()); continue; } if (currEventMessage.containsField("stop")) { long currEndTimeUnix = currEventMessage.getLong("stop"); DateTime currentEndDateTimeUTC = _initialDateTimeUTC.AddSeconds(currEndTimeUnix).ToUniversalTime(); int compResult = DateTime.Compare(currentEndDateTimeUTC, _startDateTimeUtc); if (compResult < 0) { _logger.Info("[TVHclient] GetEventsResponseHandler.handleResponse: stop value of event smaller query start value - skipping! \n" + "Query start UTC dateTime: " + _startDateTimeUtc + "\n" + "Query end UTC dateTime: " + _endDateTimeUtc + "\n" + "Event start UTC dateTime: " + currentEndDateTimeUTC + "\n" + currEventMessage.ToString()); continue; } pi.EndDate = currentEndDateTimeUTC; } else { _logger.Info("[TVHclient] GetEventsResponseHandler.handleResponse: no stop value for event - skipping! \n" + currEventMessage.ToString()); continue; } if (currEventMessage.containsField("channelId")) { pi.ChannelId = "" + currEventMessage.getInt("channelId"); } if (currEventMessage.containsField("eventId")) { pi.Id = "" + currEventMessage.getInt("eventId"); } if (currEventMessage.containsField("title")) { pi.Name = currEventMessage.getString("title"); } if (currEventMessage.containsField("description")) { pi.Overview = currEventMessage.getString("description"); } if (currEventMessage.containsField("summary")) { pi.EpisodeTitle = currEventMessage.getString("summary"); } if (currEventMessage.containsField("firstAired")) { long firstAiredUtcLong = currEventMessage.getLong("firstAired"); pi.OriginalAirDate = _initialDateTimeUTC.AddSeconds(firstAiredUtcLong).ToUniversalTime(); } if (currEventMessage.containsField("starRating")) { pi.OfficialRating = "" + currEventMessage.getInt("starRating"); } if (currEventMessage.containsField("image")) { pi.HasImage = true; pi.ImageUrl = "" + currEventMessage.getString("image"); } else { pi.HasImage = false; } if (currEventMessage.containsField("contentType")) { List<string> genres = new List<string>(); int contentType = currEventMessage.getInt("contentType"); //byte major = (byte)((contentTypeRaw & 0xF0) >> 4); //byte minor = (byte) (contentTypeRaw & 0xF); switch (contentType) { // movie/drama case 0x10: genres.Add("Drama"); genres.Add("Movie"); pi.IsMovie = true; break; case 0x11: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Detective"); genres.Add("Thriller"); pi.IsMovie = true; break; case 0x12: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Adventure"); genres.Add("Western"); genres.Add("War"); pi.IsMovie = true; break; case 0x13: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Science Fiction"); genres.Add("Fantasy"); genres.Add("Horror"); pi.IsMovie = true; break; case 0x14: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Comedy"); pi.IsMovie = true; break; case 0x15: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Soap"); genres.Add("Melodrama"); genres.Add("Folkloric"); pi.IsMovie = true; break; case 0x16: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Romance"); pi.IsMovie = true; break; case 0x17: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Serious"); genres.Add("ClassicalReligion"); genres.Add("Historical"); pi.IsMovie = true; break; case 0x18: genres.Add("Drama"); genres.Add("Movie"); genres.Add("Adult Movie"); pi.IsMovie = true; break; // news/current affairs case 0x20: genres.Add("News"); genres.Add("Current Affairs"); pi.IsNews = true; break; case 0x21: genres.Add("News"); genres.Add("Current Affairs"); genres.Add("Weather Report"); pi.IsNews = true; break; case 0x22: genres.Add("News"); genres.Add("Current Affairs"); genres.Add("Magazine"); pi.IsNews = true; break; case 0x23: genres.Add("News"); genres.Add("Current Affairs"); genres.Add("Documentary"); pi.IsNews = true; break; case 0x24: genres.Add("News"); genres.Add("Current Affairs"); genres.Add("Discussion"); genres.Add("Interview"); genres.Add("Debate"); pi.IsNews = true; break; // show/game show case 0x30: genres.Add("Show"); genres.Add("Game Show"); break; case 0x31: genres.Add("Show"); genres.Add("Game Show"); genres.Add("Quiz"); genres.Add("Contest"); break; case 0x32: genres.Add("Show"); genres.Add("Game Show"); genres.Add("Variety"); break; case 0x33: genres.Add("Show"); genres.Add("Game Show"); genres.Add("Talk"); break; // sports case 0x40: genres.Add("Sports"); pi.IsSports = true; break; case 0x41: genres.Add("Sports"); genres.Add("Special Event"); pi.IsSports = true; break; case 0x42: genres.Add("Sports"); genres.Add("Magazine"); pi.IsSports = true; break; case 0x43: genres.Add("Sports"); genres.Add("Football"); genres.Add("Soccer"); pi.IsSports = true; break; case 0x44: genres.Add("Sports"); genres.Add("Tennis"); genres.Add("Squash"); pi.IsSports = true; break; case 0x45: genres.Add("Sports"); genres.Add("Team Sports"); pi.IsSports = true; break; case 0x46: genres.Add("Sports"); genres.Add("Athletics"); pi.IsSports = true; break; case 0x47: genres.Add("Sports"); genres.Add("Motor Sport"); pi.IsSports = true; break; case 0x48: genres.Add("Sports"); genres.Add("Water Sport"); pi.IsSports = true; break; case 0x49: genres.Add("Sports"); genres.Add("Winter Sport"); pi.IsSports = true; break; case 0x4a: genres.Add("Sports"); genres.Add("Equestrian"); pi.IsSports = true; break; case 0x4b: genres.Add("Sports"); genres.Add("Martial Sports"); pi.IsSports = true; break; // childrens/youth case 0x50: genres.Add("Childrens"); genres.Add("Youth"); pi.IsKids = true; break; case 0x51: genres.Add("Childrens"); genres.Add("Youth"); genres.Add("Pre-school"); pi.IsKids = true; break; case 0x52: genres.Add("Childrens"); genres.Add("Youth"); genres.Add("Entertainment (6 to 14 year-olds)"); pi.IsKids = true; break; case 0x53: genres.Add("Childrens"); genres.Add("Youth"); genres.Add("Entertainment (10 to 16 year-olds)"); pi.IsKids = true; break; case 0x54: genres.Add("Childrens"); genres.Add("Youth"); genres.Add("Informational"); genres.Add("Educational"); genres.Add("Schools"); pi.IsKids = true; break; case 0x55: genres.Add("Childrens"); genres.Add("Youth"); genres.Add("Cartoons"); genres.Add("Puppets"); pi.IsKids = true; break; // music/ballet/dance case 0x60: genres.Add("Music"); genres.Add("Ballet"); genres.Add("Dance"); break; case 0x61: genres.Add("Music"); genres.Add("Ballet"); genres.Add("Dance"); genres.Add("Pop"); genres.Add("Rock"); break; case 0x62: genres.Add("Music"); genres.Add("Ballet"); genres.Add("Dance"); genres.Add("Serious Music"); genres.Add("Classical Music"); break; case 0x63: genres.Add("Music"); genres.Add("Ballet"); genres.Add("Dance"); genres.Add("Folk"); genres.Add("Traditional Music"); break; case 0x64: genres.Add("Music"); genres.Add("Ballet"); genres.Add("Dance"); genres.Add("Jazz"); break; case 0x65: genres.Add("Music"); genres.Add("Ballet"); genres.Add("Dance"); genres.Add("Musical"); genres.Add("Opera"); break; case 0x66: genres.Add("Music"); genres.Add("Ballet"); genres.Add("Dance"); break; // arts/culture case 0x70: genres.Add("Arts"); genres.Add("Culture"); break; case 0x71: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Performing Arts"); break; case 0x72: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Fine Arts"); break; case 0x73: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Religion"); break; case 0x74: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Popular Culture"); genres.Add("Tradital Arts"); break; case 0x75: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Literature"); break; case 0x76: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Film"); genres.Add("Cinema"); break; case 0x77: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Experimantal Film"); genres.Add("Video"); break; case 0x78: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Broadcasting"); genres.Add("Press"); break; case 0x79: genres.Add("Arts"); genres.Add("Culture"); genres.Add("New Media"); break; case 0x7a: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Magazine"); break; case 0x7b: genres.Add("Arts"); genres.Add("Culture"); genres.Add("Fashion"); break; // social/political/economic case 0x80: genres.Add("Social"); genres.Add("Political"); genres.Add("Economic"); break; case 0x81: genres.Add("Social"); genres.Add("Political"); genres.Add("Economic"); genres.Add("Magazin"); genres.Add("Report"); genres.Add("Documentary"); break; case 0x82: genres.Add("Social"); genres.Add("Political"); genres.Add("Economic"); genres.Add("Economics"); genres.Add("Social Advisory"); break; case 0x83: genres.Add("Social"); genres.Add("Political"); genres.Add("Economic"); genres.Add("Remarkable People"); break; // children's youth: educational/science/factual case 0x90: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); pi.IsKids = true; break; case 0x91: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); genres.Add("Nature"); genres.Add("Animals"); genres.Add("Environment"); pi.IsKids = true; break; case 0x92: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); genres.Add("Technology"); genres.Add("Natural Sciences"); pi.IsKids = true; break; case 0x93: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); genres.Add("Medicine"); genres.Add("Physiology"); genres.Add("Psychology"); pi.IsKids = true; break; case 0x94: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); genres.Add("Foreign Countries"); genres.Add("Expeditions"); pi.IsKids = true; break; case 0x95: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); genres.Add("Social"); genres.Add("Spiritual Sciences"); pi.IsKids = true; break; case 0x96: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); genres.Add("Further Education"); pi.IsKids = true; break; case 0x97: genres.Add("Educational"); genres.Add("Science"); genres.Add("Factual"); genres.Add("Languages"); pi.IsKids = true; break; // leisure hobbies case 0xa0: genres.Add("Leisure"); genres.Add("Hobbies"); break; case 0xa1: genres.Add("Leisure"); genres.Add("Hobbies"); genres.Add("Tourism"); genres.Add("Travel"); break; case 0xa2: genres.Add("Leisure"); genres.Add("Hobbies"); genres.Add("Handicraft"); break; case 0xa3: genres.Add("Leisure"); genres.Add("Hobbies"); genres.Add("Motoring"); break; case 0xa4: genres.Add("Leisure"); genres.Add("Hobbies"); genres.Add("Fitness"); genres.Add("Health"); break; case 0xa5: genres.Add("Leisure"); genres.Add("Hobbies"); genres.Add("Cooking"); break; case 0xa6: genres.Add("Leisure"); genres.Add("Hobbies"); genres.Add("Advertisement"); genres.Add("Shopping"); break; case 0xa7: genres.Add("Leisure"); genres.Add("Hobbies"); genres.Add("Gardening"); break; // misc case 0xb0: genres.Add("Original Language"); break; case 0xb1: genres.Add("Black and White"); break; case 0xb2: genres.Add("Unpublished"); break; case 0xb3: genres.Add("Live Broadcast"); pi.IsLive = true; break; // drama (user defined, specced in the UK "D-Book") case 0xf0: genres.Add("Drama"); pi.IsMovie = true; break; case 0xf1: genres.Add("Drama"); genres.Add("Detective"); genres.Add("Thriller"); pi.IsMovie = true; break; case 0xf2: genres.Add("Drama"); genres.Add("Adventure"); genres.Add("Western"); genres.Add("War"); pi.IsMovie = true; break; case 0xf3: genres.Add("Drama"); genres.Add("Science Fiction"); genres.Add("Fantasy"); genres.Add("Horror"); pi.IsMovie = true; break; case 0xf4: genres.Add("Drama"); genres.Add("Commedy"); pi.IsMovie = true; break; case 0xf5: genres.Add("Drama"); genres.Add("Soap"); genres.Add("Melodrama"); genres.Add("Folkloric"); pi.IsMovie = true; break; case 0xf6: genres.Add("Drama"); genres.Add("Romance"); break; case 0xf7: genres.Add("Drama"); genres.Add("Serious"); genres.Add("ClassicalReligion"); genres.Add("Historical"); pi.IsMovie = true; break; case 0xf8: genres.Add("Drama"); genres.Add("Adult"); pi.IsMovie = true; break; default: // unused values break; } pi.Genres = genres; } //pi.IsSeries - bool //pi.CommunityRating - float //pi.IsHD - bool //pi.IsPremiere - bool //pi.IsRepeat - bool //pi.ImagePath - string //pi.Audio - MediaBrowser.Model.LiveTv.ProgramAudio //pi.ProductionYear - int _logger.Info("[TVHclient] GetEventsResponseHandler.handleResponse: add event\n" + currEventMessage.ToString() + "\n" + createPiInfo(pi)); _result.Add(pi); } } _dataReady = true; }
public async Task<MediaSourceInfo> GetRecordingStream(string recordingId, string mediaSourceId, CancellationToken cancellationToken) { ensureConnection(); HTSMessage getTicketMessage = new HTSMessage(); getTicketMessage.Method = "getTicket"; getTicketMessage.putField("dvrId", recordingId); //HTSMessage getTicketResponse = await Task.Factory.StartNew<HTSMessage>(() => //{ // LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); // _htsConnection.sendMessage(getTicketMessage, lbrh); // return lbrh.getResponse(); //}); TaskWithTimeoutRunner<HTSMessage> twtr = new TaskWithTimeoutRunner<HTSMessage>(TIMEOUT); TaskWithTimeoutResult<HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew<HTSMessage>(() => { LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); _htsConnection.sendMessage(getTicketMessage, lbrh); return lbrh.getResponse(); })); if (twtRes.HasTimeout) { _logger.Error("[TVHclient] Can't delete recording because of timeout"); } else { HTSMessage getTicketResponse = twtRes.Result; if (_subscriptionId == int.MaxValue) { _subscriptionId = 0; } int currSubscriptionId = _subscriptionId++; return new MediaSourceInfo { Id = "" + currSubscriptionId, Path = _httpBaseUrl + getTicketResponse.getString("path") + "?ticket=" + getTicketResponse.getString("ticket"), Protocol = MediaProtocol.Http, MediaStreams = new List<MediaStream> { new MediaStream { Type = MediaStreamType.Video, // Set the index to -1 because we don't know the exact index of the video stream within the container Index = -1, // Set to true if unknown to enable deinterlacing IsInterlaced = true }, new MediaStream { Type = MediaStreamType.Audio, // Set the index to -1 because we don't know the exact index of the audio stream within the container Index = -1 } } }; } throw new TimeoutException(); }
/// <summary> /// Cancel the Series Timer /// </summary> /// <param name="timerId">The Timer Id</param> /// <param name="cancellationToken">The CancellationToken</param> /// <returns></returns> public async Task CancelSeriesTimerAsync(string timerId, CancellationToken cancellationToken) { ensureConnection(); int timeOut = await WaitForInitialLoadTask(cancellationToken); if (timeOut == -1 || cancellationToken.IsCancellationRequested) { _logger.Info("[TVHclient] CancelSeriesTimerAsync, call canceled or timed out."); return; } HTSMessage deleteAutorecMessage = new HTSMessage(); deleteAutorecMessage.Method = "deleteAutorecEntry"; deleteAutorecMessage.putField("id", timerId); //HTSMessage deleteAutorecResponse = await Task.Factory.StartNew<HTSMessage>(() => //{ // LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); // _htsConnection.sendMessage(deleteAutorecMessage, lbrh); // return lbrh.getResponse(); //}); TaskWithTimeoutRunner<HTSMessage> twtr = new TaskWithTimeoutRunner<HTSMessage>(TIMEOUT); TaskWithTimeoutResult<HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew<HTSMessage>(() => { LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); _htsConnection.sendMessage(deleteAutorecMessage, lbrh); return lbrh.getResponse(); })); if (twtRes.HasTimeout) { _logger.Error("[TVHclient] Can't delete recording because of timeout"); } else { HTSMessage deleteAutorecResponse = twtRes.Result; Boolean success = deleteAutorecResponse.getInt("success", 0) == 1; if (!success) { _logger.Error("[TVHclient] Can't cancel timer: '" + deleteAutorecResponse.getString("error") + "'"); } } }
/// <summary> /// Update a single Timer /// </summary> /// <param name="info">The program info</param> /// <param name="cancellationToken">The CancellationToken</param> /// <returns></returns> public async Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellationToken) { ensureConnection(); int timeOut = await WaitForInitialLoadTask(cancellationToken); if (timeOut == -1 || cancellationToken.IsCancellationRequested) { _logger.Info("[TVHclient] UpdateTimerAsync, call canceled or timed out."); return; } HTSMessage updateTimerMessage = new HTSMessage(); updateTimerMessage.Method = "updateDvrEntry"; updateTimerMessage.putField("id", info.Id); updateTimerMessage.putField("startExtra", (long)(info.PrePaddingSeconds / 60)); updateTimerMessage.putField("stopExtra", (long)(info.PostPaddingSeconds / 60)); //HTSMessage updateTimerResponse = await Task.Factory.StartNew<HTSMessage>(() => //{ // LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); // _htsConnection.sendMessage(updateTimerMessage, lbrh); // return lbrh.getResponse(); //}); TaskWithTimeoutRunner<HTSMessage> twtr = new TaskWithTimeoutRunner<HTSMessage>(TIMEOUT); TaskWithTimeoutResult<HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew<HTSMessage>(() => { LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); _htsConnection.sendMessage(updateTimerMessage, lbrh); return lbrh.getResponse(); })); if (twtRes.HasTimeout) { _logger.Error("[TVHclient] Can't update timer because of timeout"); } else { HTSMessage updateTimerResponse = twtRes.Result; Boolean success = updateTimerResponse.getInt("success", 0) == 1; if (!success) { _logger.Error("[TVHclient] Can't update timer: '" + updateTimerResponse.getString("error") + "'"); } } }
/// <summary> /// Create a new recording /// </summary> /// <param name="info">The TimerInfo</param> /// <param name="cancellationToken">The cancellationToken</param> /// <returns></returns> public async Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken) { ensureConnection(); int timeOut = await WaitForInitialLoadTask(cancellationToken); if (timeOut == -1 || cancellationToken.IsCancellationRequested) { _logger.Info("[TVHclient] CreateTimerAsync, call canceled or timed out."); return; } HTSMessage createTimerMessage = new HTSMessage(); createTimerMessage.Method = "addDvrEntry"; createTimerMessage.putField("channelId", info.ChannelId); createTimerMessage.putField("start", DateTimeHelper.getUnixUTCTimeFromUtcDateTime(info.StartDate)); createTimerMessage.putField("stop", DateTimeHelper.getUnixUTCTimeFromUtcDateTime(info.EndDate)); createTimerMessage.putField("startExtra", (long)(info.PrePaddingSeconds / 60)); createTimerMessage.putField("stopExtra", (long)(info.PostPaddingSeconds / 60)); createTimerMessage.putField("priority", _priority); // info.Priority delivers always 0 - no GUI createTimerMessage.putField("configName", _profile); createTimerMessage.putField("description", info.Overview); createTimerMessage.putField("title", info.Name); createTimerMessage.putField("creator", Plugin.Instance.Configuration.Username); //HTSMessage createTimerResponse = await Task.Factory.StartNew<HTSMessage>(() => //{ // LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); // _htsConnection.sendMessage(createTimerMessage, lbrh); // return lbrh.getResponse(); //}); TaskWithTimeoutRunner<HTSMessage> twtr = new TaskWithTimeoutRunner<HTSMessage>(TIMEOUT); TaskWithTimeoutResult<HTSMessage> twtRes = await twtr.RunWithTimeout(Task.Factory.StartNew<HTSMessage>(() => { LoopBackResponseHandler lbrh = new LoopBackResponseHandler(); _htsConnection.sendMessage(createTimerMessage, lbrh); return lbrh.getResponse(); })); if (twtRes.HasTimeout) { _logger.Error("[TVHclient] Can't create timer because of timeout"); } else { HTSMessage createTimerResponse = twtRes.Result; Boolean success = createTimerResponse.getInt("success", 0) == 1; if (!success) { _logger.Error("[TVHclient] Can't create timer: '" + createTimerResponse.getString("error") + "'"); } } }
public void sendMessage(HTSMessage message, HTSResponseHandler responseHandler) { // loop the sequence number if (_seq == int.MaxValue) { _seq = int.MinValue; } else { _seq++; } // housekeeping verry old response handlers if (_responseHandlers.ContainsKey(_seq)) { _responseHandlers.Remove(_seq); } message.putField("seq", _seq); _messagesForSendQueue.Enqueue(message); _responseHandlers.Add(_seq, responseHandler); }