Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix channel images #72

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 3 additions & 34 deletions TVHeadEnd/HTSConnectionHandler.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
Expand Down Expand Up @@ -162,11 +160,11 @@ private void init()
if (_enableSubsMaudios)
{
// Use HTTP basic auth instead of TVH ticketing system for authentication to allow the users to switch subs or audio tracks at any time
_httpBaseUrl = "http://" + _userName + ":" + _password + "@" + _tvhServerName + ":" + _httpPort + _webRoot;
_httpBaseUrl = $"http://{Uri.EscapeDataString(_userName)}:{Uri.EscapeDataString(_password)}@{_tvhServerName}:{_httpPort}{_webRoot}";
}
else
{
_httpBaseUrl = "http://" + _tvhServerName + ":" + _httpPort + _webRoot;
_httpBaseUrl = $"http://{_tvhServerName}:{_httpPort}{_webRoot}";
}

string authInfo = _userName + ":" + _password;
Expand Down Expand Up @@ -194,7 +192,7 @@ public async Task<ImageStream> GetChannelImage(string channelId, CancellationTok
}
else
{
string requestStr = "http://" + _tvhServerName + ":" + _httpPort + _webRoot + "/" + channelIcon;
string requestStr = $"http://{_tvhServerName}:{_httpPort}{_webRoot}/{channelIcon}";
request.RequestUri = new Uri(requestStr);
request.Headers.Authorization = AuthenticationHeaderValue.Parse(_headers[HeaderNames.Authorization]);

Expand Down Expand Up @@ -278,40 +276,11 @@ public async Task<ImageStream> GetChannelImage(string channelId, CancellationTok
}
}

public string GetChannelImageUrl(string channelId)
{
_logger.LogDebug("[TVHclient] HTSConnectionHandler.GetChannelImage: channelId: {id}", channelId);

String channelIcon = _channelDataHelper.GetChannelIcon4ChannelId(channelId);

if (string.IsNullOrEmpty(channelIcon))
{
return null;
}

if (channelIcon.StartsWith("http"))
{
return _channelDataHelper.GetChannelIcon4ChannelId(channelId);
}
else
{
return "http://" + _userName + ":" + _password + "@" +_tvhServerName + ":" + _httpPort + _webRoot + "/" + channelIcon;
}
}

public Dictionary<string, string> GetHeaders()
{
return new Dictionary<string, string>(_headers);
}

//private static Stream ImageToPNGStream(Image image)
//{
// Stream stream = new System.IO.MemoryStream();
// image.Save(stream, ImageFormat.Png);
// stream.Position = 0;
// return stream;
//}

private void ensureConnection()
{
//_logger.LogDebug("[TVHclient] HTSConnectionHandler.ensureConnection");
Expand Down
148 changes: 32 additions & 116 deletions TVHeadEnd/LiveTvService.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
Expand All @@ -23,14 +21,11 @@

namespace TVHeadEnd
{
public class LiveTvService : ILiveTvService
public class LiveTvService : ILiveTvService, IDynamicImageProvider
{
public event EventHandler DataSourceChanged;
public event EventHandler<RecordingStatusChangedEventArgs> RecordingStatusChanged;

//Added for stream probing
private readonly IMediaEncoder _mediaEncoder;

private readonly TimeSpan TIMEOUT = TimeSpan.FromMinutes(5);

private HTSConnectionHandler _htsConnectionHandler;
Expand All @@ -39,9 +34,8 @@ public class LiveTvService : ILiveTvService
private readonly ILogger<LiveTvService> _logger;
public DateTime LastRecordingChange = DateTime.MinValue;

public LiveTvService(ILoggerFactory loggerFactory, IMediaEncoder mediaEncoder, IHttpClientFactory httpClientFactory)
public LiveTvService(ILoggerFactory loggerFactory, IHttpClientFactory httpClientFactory)
{
//System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();
_logger = loggerFactory.CreateLogger<LiveTvService>();
_logger.LogDebug("[TVHclient] LiveTvService()");

Expand All @@ -55,9 +49,6 @@ public LiveTvService(ILoggerFactory loggerFactory, IMediaEncoder mediaEncoder, I
_channelTicketHandler = new AccessTicketHandler(loggerFactory, _htsConnectionHandler, requestTimeout, retries, lifeSpan, Channel);
_recordingTicketHandler = new AccessTicketHandler(loggerFactory, _htsConnectionHandler, requestTimeout, retries, lifeSpan, Recording);
}

//Added for stream probing
_mediaEncoder = mediaEncoder;
}

public string HomePageUrl { get { return "http://tvheadend.org/"; } }
Expand Down Expand Up @@ -201,88 +192,9 @@ await Task.Factory.StartNew<string>(() =>
});
}

public async Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
public Task CreateSeriesTimerAsync(SeriesTimerInfo info, CancellationToken cancellationToken)
{
// Dummy method to avoid warnings
await Task.Factory.StartNew<int>(() => { return 0; });

throw new NotImplementedException();


//int timeOut = await WaitForInitialLoadTask(cancellationToken);
//if (timeOut == -1 || cancellationToken.IsCancellationRequested)
//{
// _logger.LogDebug("[TVHclient] LiveTvService.CreateSeriesTimerAsync: call cancelled or timed out - returning empty list");
// return;
//}

////_logger.LogDebug("[TVHclient] LiveTvService.CreateSeriesTimerAsync: got SeriesTimerInfo: {spam}", dump(info));

//HTSMessage createSeriesTimerMessage = new HTSMessage();
//createSeriesTimerMessage.Method = "addAutorecEntry";
//createSeriesTimerMessage.putField("title", info.Name);
//if (!info.RecordAnyChannel)
//{
// createSeriesTimerMessage.putField("channelId", info.ChannelId);
//}
//createSeriesTimerMessage.putField("minDuration", 0);
//createSeriesTimerMessage.putField("maxDuration", 0);

//int tempPriority = info.Priority;
//if (tempPriority == 0)
//{
// tempPriority = _priority; // info.Priority delivers 0 if timers is newly created - no GUI
//}
//createSeriesTimerMessage.putField("priority", tempPriority);
//createSeriesTimerMessage.putField("configName", _profile);
//createSeriesTimerMessage.putField("daysOfWeek", AutorecDataHelper.getDaysOfWeekFromList(info.Days));

//if (!info.RecordAnyTime)
//{
// createSeriesTimerMessage.putField("approxTime", AutorecDataHelper.getMinutesFromMidnight(info.StartDate));
//}
//createSeriesTimerMessage.putField("startExtra", (long)(info.PrePaddingSeconds / 60L));
//createSeriesTimerMessage.putField("stopExtra", (long)(info.PostPaddingSeconds / 60L));
//createSeriesTimerMessage.putField("comment", info.Overview);


////_logger.LogDebug("[TVHclient] LiveTvService.CreateSeriesTimerAsync: created HTSP message: {msg}", createSeriesTimerMessage.ToString());


///*
// public DateTime EndDate { get; set; }
// public string ProgramId { get; set; }
// public bool RecordNewOnly { get; set; }
// */

////HTSMessage createSeriesTimerResponse = await Task.Factory.StartNew<HTSMessage>(() =>
////{
//// LoopBackResponseHandler lbrh = new LoopBackResponseHandler();
//// _htsConnection.sendMessage(createSeriesTimerMessage, 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(createSeriesTimerMessage, lbrh);
// return lbrh.getResponse();
//}));

//if (twtRes.HasTimeout)
//{
// _logger.LogError("[TVHclient] LiveTvService.CreateSeriesTimerAsync: can't create series because the timeout was reached");
//}
//else
//{
// HTSMessage createSeriesTimerResponse = twtRes.Result;
// Boolean success = createSeriesTimerResponse.getInt("success", 0) == 1;
// if (!success)
// {
// _logger.LogError("[TVHclient] LiveTvService.CreateSeriesTimerAsync: can't create series timer: '{why}'", createSeriesTimerResponse.getString("error"));
// }
//}
}

public async Task CreateTimerAsync(TimerInfo info, CancellationToken cancellationToken)
Expand Down Expand Up @@ -399,17 +311,7 @@ public async Task<IEnumerable<ChannelInfo>> GetChannelsAsync(CancellationToken c
return new List<ChannelInfo>();
}

var list = twtRes.Result.ToList();

foreach (var channel in list)
{
if (string.IsNullOrEmpty(channel.ImageUrl))
{
channel.ImageUrl = _htsConnectionHandler.GetChannelImageUrl(channel.Id);
}
}

return list;
return twtRes.Result.ToList();
}

public async Task<MediaSourceInfo> GetChannelStream(string channelId, string mediaSourceId, CancellationToken cancellationToken)
Expand Down Expand Up @@ -497,12 +399,6 @@ public async Task<SeriesTimerInfo> GetNewTimerDefaultsAsync(CancellationToken ca
});
}

public Task<ImageStream> GetProgramImageAsync(string programId, string channelId, CancellationToken cancellationToken)
{
// Leave as is. This is handled by supplying image url to ProgramInfo
throw new NotImplementedException();
}

public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{
int timeOut = await WaitForInitialLoadTask(cancellationToken);
Expand Down Expand Up @@ -535,12 +431,6 @@ public async Task<IEnumerable<ProgramInfo>> GetProgramsAsync(string channelId, D
return twtRes.Result;
}

public Task<ImageStream> GetRecordingImageAsync(string recordingId, CancellationToken cancellationToken)
{
// Leave as is. This is handled by supplying image url to RecordingInfo
throw new NotImplementedException();
}

public async Task<IEnumerable<MyRecordingInfo>> GetAllRecordingsAsync(CancellationToken cancellationToken)
{
// retrieve all 'Pending', 'Inprogress' and 'Completed' recordings
Expand Down Expand Up @@ -794,6 +684,32 @@ public async Task UpdateTimerAsync(TimerInfo info, CancellationToken cancellatio
}
}

public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new[] { ImageType.Primary };
}

public async Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
{
var image = await _htsConnectionHandler.GetChannelImage(item.ExternalId, cancellationToken);
if (image == null)
{
return new DynamicImageResponse();
}

return new DynamicImageResponse
{
Format = image.Format,
Stream = image.Stream,
HasImage = true,
};
}

public bool Supports(BaseItem item)
{
return item.ServiceName == Name && item is LiveTvChannel;
}

/***********/
/* Helpers */
/***********/
Expand Down
6 changes: 3 additions & 3 deletions TVHeadEnd/RecordingsChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public Task<DynamicImageResponse> GetChannelImage(ImageType type, CancellationTo
{
return Task.FromResult(new DynamicImageResponse
{
Path = "https://github.com/MediaBrowser/Tvheadend/raw/master/TVHeadEnd/Images/TVHeadEnd.png?raw=true",
Path = "https://repo.jellyfin.org/releases/plugin/images/jellyfin-plugin-tvheadend.png",
Protocol = MediaProtocol.Http,
HasImage = true
});
Expand Down Expand Up @@ -268,14 +268,14 @@ private static string buildRecordingPath(string Id)
var tvhServerName = config.TVH_ServerName.Trim();
var httpPort = config.HTTP_Port;
var htspPort = config.HTSP_Port;
var webRoot = config.WebRoot;
var webRoot = config.WebRoot;
if (webRoot.EndsWith("/"))
{
webRoot = webRoot.Substring(0, webRoot.Length - 1);
}
var userName = config.Username.Trim();
var password = config.Password.Trim();
return "http://" + userName + ":" + password + "@" + tvhServerName + ":" + httpPort + webRoot + "/dvrfile/" + Id;
return $"http://{Uri.EscapeDataString(userName)}:{Uri.EscapeDataString(password)}@{tvhServerName}:{httpPort}{webRoot}/dvrfile/{Id}";
}
catch (Exception)
{
Expand Down