网站首页 网站源码
using Dpz.Core.Public.ViewModel.Response;
using Dpz.Core.Shard.Service;
using Dpz.Core.WebApi.Models.Request;
namespace Dpz.Core.WebApi.Controllers;
/// <summary>
/// 视频
/// </summary>
[ApiController, Route("api/[controller]")]
public class VideoController(
IBarrageService barrageService,
IVideoService videoService,
IHybridCachingProvider hybridCachingProvider,
IVideoShardService videoShardService,
IVideoCloudService videoCloudService
) : ControllerBase
{
/// <summary>
/// 获取视频列表
/// </summary>
/// <returns></returns>
[HttpGet]
[ProducesResponseType<List<VmVideo>>(StatusCodes.Status200OK)]
public async Task<IActionResult> GetVideos()
{
var videos = await videoShardService.GetVideosAsync();
return Ok(videos);
}
/// <summary>
/// 发送弹幕
/// </summary>
/// <param name="danmaku"></param>
/// <returns></returns>
[HttpPost("danmaku/v3")]
[ProducesResponseType<VideoDanmakuDto>(StatusCodes.Status200OK)]
public async Task<IActionResult> Danmaku([FromBody] VideoDanmakuDto danmaku)
{
var vmBarrage = new VmBarrage
{
Color = danmaku.Color.ToString(),
Group = danmaku.Id,
Position = (int)danmaku.Type,
SendTime = DateTime.Now,
Size = 0,
Text = danmaku.Text,
Time = danmaku.Time,
};
await barrageService.AddBarrageAsync(vmBarrage);
return Ok(new { code = 0, data = danmaku });
}
/// <summary>
/// 获取视频弹幕
/// <remarks>
/// <code>V3 data[0][0] 出现时间</code>
/// <code>V3 data[0][1] 出现位置:0为滚动 1为顶部 2为底部</code>
/// <code>V3 data[0][2] 弹幕颜色</code>
/// <code>V3 data[0][3] 发送人 可以匿名发送,目前固定</code>
/// <code>V3 data[0][4] 弹幕文本</code>
/// </remarks>
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("danmaku/v3")]
[ProducesResponseType<object>(StatusCodes.Status200OK)]
public async Task<IActionResult> Danmaku(string id)
{
var danmakuList = await barrageService.GetGroupBarragesAsync(id);
var danmaku = danmakuList.Select(x =>
{
var result = int.TryParse(x.Color, out var color);
return new object[] { x.Time, x.Position, result ? color : x.Color, "阿胖", x.Text };
});
return Ok(new { code = 0, data = danmaku });
}
/// <summary>
/// 获取视频详情列表
/// </summary>
/// <returns></returns>
[HttpGet("details"), Authorize(Policy = "System")]
[ProducesResponseType<List<VmVideo>>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> GetVideoListDetails()
{
var videos = await videoShardService.GetVideosAsync();
return Ok(videos);
}
/// <summary>
/// 保存视频信息
/// </summary>
/// <returns></returns>
[HttpPost, Authorize(Policy = "System")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> SaveInformation([FromBody] VmVideo video)
{
await videoService.SaveInformationAsync(video);
await hybridCachingProvider.RemoveByPrefixAsync(CacheKey.VideoListKey);
return NoContent();
}
/// <summary>
/// 添加一次播放次数
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost("paly/{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> AddPlayer(string id)
{
await videoService.AddPlayAsync(id);
return NoContent();
}
/// <summary>
/// 获取视频元数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("meta/{id}"), Authorize(Policy = "System")]
[ProducesResponseType<VideoMetaDataResponse>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetVideoMetaData(string id)
{
var videMetaKey = $"Video-Meta:{id}";
var cacheValue = await hybridCachingProvider.GetAsync<VideoMetaDataResponse>(videMetaKey);
if (cacheValue.HasValue && cacheValue.Value != null)
{
return Ok(cacheValue.Value);
}
var video = await videoShardService.GetVideoAsync(id);
if (video == null)
{
return NotFound();
}
var meta = await videoCloudService.GetVideoMetaAsync($"/Video/{video.Title}/1080p.m3u8");
if (meta.Success)
{
await hybridCachingProvider.SetAsync(videMetaKey, meta.Data, TimeSpan.FromDays(90));
return Ok(meta.Data);
}
return BadRequest(meta.Message);
}
/// <summary>
/// 设置视频缩略图
/// </summary>
/// <param name="id"></param>
/// <param name="request"></param>
/// <returns></returns>
[HttpPatch("screenshot/{id}"), Authorize(Policy = "System")]
[ProducesResponseType<string>(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> SetVideoScreenshot(
string id,
[FromBody] ScreenshotRequest request
)
{
var video = await videoShardService.GetVideoAsync(id);
if (video == null)
{
return NotFound();
}
var meta = await videoCloudService.GetVideoMetaAsync($"/Video/{video.Title}/1080p.m3u8");
if (!meta.Success)
{
return BadRequest(meta.Message);
}
if (request.Seconds > meta.Data.Duration || request.Seconds < 0)
{
return BadRequest("时间超出范围");
}
var screenshot = await videoCloudService.VideoScreenshotAsync(
$"/Video/{video.Title}/1080p.m3u8",
TimeSpan.FromSeconds(request.Seconds)
);
if (!screenshot.Success)
{
return BadRequest(screenshot.Message);
}
return Ok(screenshot.Data);
}
}
上述代码是一个 ASP.NET Core Web API 控制器,名为 VideoController
,用于处理与视频相关的操作。以下是该控制器中各个方法的功能解释:
Dpz.Core.WebApi.Controllers
api/video
IBarrageService
、IVideoService
、IHybridCachingProvider
、IVideoShardService
和 IVideoCloudService
,这些服务用于处理弹幕、视频信息、缓存、视频分片和云视频服务等功能。GetVideos
Danmaku
danmaku/v3
VideoDanmakuDto
对象,包含弹幕的相关信息(如颜色、文本、时间等)。Danmaku
(重载)danmaku/v3
GetVideoListDetails
details
SaveInformation
VmVideo
对象,包含视频的详细信息。AddPlayer
paly/{id}
GetVideoMetaData
meta/{id}
SetVideoScreenshot
screenshot/{id}
ScreenshotRequest
对象,包含截图的时间点。这个控制器提供了一系列与视频相关的 API 接口,包括获取视频列表、发送和获取弹幕、管理视频信息、增加播放次数、获取视频元数据和设置视频缩略图等功能,适用于视频播放和管理的应用场景。