This commit is contained in:
2023-06-30 14:08:15 +01:00
commit bcaa32afb1
28 changed files with 1109 additions and 0 deletions

View File

@ -0,0 +1,60 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NostrStreamer.ApiModel;
using NostrStreamer.Database;
namespace NostrStreamer.Controllers;
[Authorize]
[Route("/api/account")]
public class AccountController : Controller
{
private readonly StreamerContext _db;
private readonly Config _config;
public AccountController(StreamerContext db, Config config)
{
_db = db;
_config = config;
}
[HttpGet]
public async Task<ActionResult> GetAccount()
{
var user = await GetUser();
if (user == default)
{
var pk = GetPubKey();
user = new()
{
PubKey = pk,
Balance = 0,
StreamKey = Guid.NewGuid().ToString()
};
_db.Users.Add(user);
await _db.SaveChangesAsync();
}
return Json(new Account
{
Url = $"rtmp://{_config.SrsPublicHost.Host}/${_config.App}",
Key = user.StreamKey
});
}
private async Task<User?> GetUser()
{
var pk = GetPubKey();
return await _db.Users.FirstOrDefaultAsync(a => a.PubKey == pk);
}
private string GetPubKey()
{
var claim = HttpContext.User.Claims.FirstOrDefault(a => a.Type == ClaimTypes.Name);
return claim!.Value;
}
}

View File

@ -0,0 +1,95 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NostrStreamer.Services;
namespace NostrStreamer.Controllers;
[Route("/api/srs")]
public class SrsController : Controller
{
private readonly ILogger<SrsController> _logger;
private readonly Config _config;
private readonly StreamManager _streamManager;
public SrsController(ILogger<SrsController> logger, Config config, StreamManager streamManager)
{
_logger = logger;
_config = config;
_streamManager = streamManager;
}
[HttpPost]
public async Task<SrsHookReply> OnStream([FromBody] SrsHook req)
{
_logger.LogInformation("OnStream: {obj}", JsonConvert.SerializeObject(req));
try
{
if (string.IsNullOrEmpty(req.Stream) || string.IsNullOrEmpty(req.App) || string.IsNullOrEmpty(req.Stream) ||
!req.App.Equals(_config.App, StringComparison.InvariantCultureIgnoreCase))
{
return new()
{
Code = 2 // invalid request
};
}
if (req.Action == "on_publish")
{
await _streamManager.StreamStarted(req.Stream);
return new();
}
if (req.Action == "on_unpublish")
{
await _streamManager.StreamStopped(req.Stream);
return new();
}
if (req.Action == "on_hls" && req.Duration.HasValue)
{
await _streamManager.ConsumeQuota(req.Stream, req.Duration.Value);
return new();
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to start stream");
}
return new()
{
Code = 1 // generic error
};
}
}
public class SrsHookReply
{
[JsonProperty("code")]
public int Code { get; init; }
}
public class SrsHook
{
[JsonProperty("action")]
public string? Action { get; set; }
[JsonProperty("client_id")]
public string? ClientId { get; set; }
[JsonProperty("ip")]
public string? Ip { get; set; }
[JsonProperty("vhost")]
public string? Vhost { get; set; }
[JsonProperty("app")]
public string? App { get; set; }
[JsonProperty("stream")]
public string? Stream { get; set; }
[JsonProperty("param")]
public string? Param { get; init; }
[JsonProperty("duration")]
public double? Duration { get; init; }
}