Based on this code HLS Proxy service for AES encrypted HLS stream I found, I got this to work.
I combined the two controllers (load/proxy) into one that I think is easier to work with
Here below is most of the code and should be enough for someone to figure this out. BUT I think you should have an updated example with this kind of code somewhere. Please share with us if you do.
Controller
[RemoteService]
[Area("app")]
[ControllerName("Manifest")]
[Route("api/app/manifest")]
public class ManifestLoadController : Controller
{
private const string ManifestProxyUrlTemplate = "http://{0}:{1}/api/app/manifest/manifestproxy";
private readonly ITopLevelManifestRetriever _topLevelManifestRetriever;
private readonly ITokenManifestInjector _tokenManifestInjector;
public ManifestLoadController(ITopLevelManifestRetriever topLevelManifestRetriever, ITokenManifestInjector tokenManifestInjector)
{
_topLevelManifestRetriever = topLevelManifestRetriever;
_tokenManifestInjector = tokenManifestInjector;
}
[AllowAnonymous]
[HttpGet]
[Route("manifestload")]
public virtual IActionResult GetLoad(string playbackUrl, string webtoken)
{
if (playbackUrl == null || webtoken == null)
return BadRequest("playbackUrl or webtoken cannot be empty");
if (playbackUrl.Contains("&", StringComparison.OrdinalIgnoreCase))
{
playbackUrl = playbackUrl.Remove(playbackUrl.IndexOf("&"));
}
var token = webtoken;
var modifiedTopLeveLManifest = _topLevelManifestRetriever.GetTopLevelManifestForToken(GetManifestProxyUrl(Request), playbackUrl, token);
var response = new ContentResult
{
Content = modifiedTopLeveLManifest,
ContentType = @"application/vnd.apple.mpegurl"
};
Response.Headers.Add("Access-Control-Allow-Origin", "*");
Response.Headers.Add("X-Content-Type-Options", "nosniff");
Response.Headers.Add("Cache-Control", "max-age=259200");
return response;
}
[AllowAnonymous]
[HttpGet]
[Produces("application/vnd.apple.mpegurl")]
[Route("manifestproxy")]
public IActionResult GetProxy(string playbackUrl, string token)
{
var collection = HttpUtility.ParseQueryString(token);
var authToken = collection[0];
var armoredAuthToken = HttpUtility.UrlEncode(authToken);
var httpRequest = (HttpWebRequest)WebRequest.Create(new Uri(playbackUrl));
httpRequest.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
httpRequest.Timeout = 30000;
var httpResponse = httpRequest.GetResponse();
//var response = this.Request.ReadFormAsync().Result;
var response = new ContentResult();
try
{
var stream = httpResponse.GetResponseStream();
if (stream != null)
{
using (var reader = new StreamReader(stream))
{
var content = reader.ReadToEnd();
response.Content =
_tokenManifestInjector.InjetTokenToManifestChunks(playbackUrl, armoredAuthToken, content);
}
}
}
finally
{
httpResponse.Close();
}
Response.Headers.Add("Access-Control-Allow-Origin", "*");
return response;
}
private static string GetManifestProxyUrl(HttpRequest request)
{
var hostPortion = request.Host.Host;
var port = request.Host.Port.GetValueOrDefault(80);
var manifestProxyUrl = string.Format(ManifestProxyUrlTemplate, hostPortion, port);
return manifestProxyUrl;
}
}
cshtml view
<video id="azuremediaplayer" class="azuremediaplayer amp-default-skin amp-big-play-centered"> </video>
<script>
var myOptions = {
autoplay: true,
controls: true,
width: "100%",
height: "300",
poster: "",
"logo": { "enabled": false },
//preload: true,
//poster: url
};
var myPlayer = amp("appleplayer", myOptions);
myPlayer.src([{ src: "@Model.ManifestUrl", type: "application/vnd.ms-sstr+xml", streamingFormats: ["DASH", "SMOOTH"], protectionInfo: [{ type: "AES", authenticationToken: "@Model.Token" }] }, { src: "@Html.Raw(@Model.LiveStreamUrl)", type: "application/vnd.apple.mpegurl", disableUrlRewriter: true, protectionInfo: [{ type: "AES" }] }]);
</script>
public async Task OnGet(Guid Id)
{
var @event = GetTokenFromService(id);
if (OnApple)
{
LiveStreamUrl = $"https://{Request.Host}/api/app/manifest/manifestload?playbackUrl={@event.HlsUrl}&webtoken={@event.Token}";
Token = @event.Token;
ManifestUrl = @event.HlsUrl;
}
else
{
LiveStreamUrl = @event.DashUrl;
Token = $"Bearer={@event.Token}";
ManifestUrl = @event.DashUrl;
DebugUrl = $"https://ampdemo.azureedge.net/?url={LiveStreamUrl}&playready=true&widevine=true&token={Token}";
}
}
For browser detection I´m using https://www.nuget.org/packages/Shyjus.BrowserDetector/