网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
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);
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码是一个 ASP.NET Core Web API 控制器,名为 VideoController,用于处理与视频相关的操作。以下是该控制器中各个方法的功能解释:

1. 控制器概述

  • 命名空间: Dpz.Core.WebApi.Controllers
  • 路由: api/video
  • 依赖注入: 控制器通过构造函数注入了多个服务,包括 IBarrageServiceIVideoServiceIHybridCachingProviderIVideoShardServiceIVideoCloudService,这些服务用于处理弹幕、视频信息、缓存、视频分片和云视频服务等功能。

2. 方法功能

GetVideos

  • HTTP 方法: GET
  • 功能: 获取视频列表。
  • 返回: 返回一个视频列表的 JSON 响应。

Danmaku

  • HTTP 方法: POST
  • 路由: danmaku/v3
  • 功能: 发送弹幕。
  • 参数: 接收一个 VideoDanmakuDto 对象,包含弹幕的相关信息(如颜色、文本、时间等)。
  • 返回: 返回发送的弹幕信息。

Danmaku (重载)

  • HTTP 方法: GET
  • 路由: danmaku/v3
  • 功能: 获取指定视频的弹幕。
  • 参数: 视频 ID。
  • 返回: 返回该视频的弹幕列表,格式化为特定的数组结构。

GetVideoListDetails

  • HTTP 方法: GET
  • 路由: details
  • 功能: 获取视频详情列表(需要授权)。
  • 返回: 返回视频的详细信息列表。

SaveInformation

  • HTTP 方法: POST
  • 功能: 保存视频信息(需要授权)。
  • 参数: 接收一个 VmVideo 对象,包含视频的详细信息。
  • 返回: 返回204 No Content,表示成功。

AddPlayer

  • HTTP 方法: POST
  • 路由: paly/{id}
  • 功能: 增加视频的播放次数。
  • 参数: 视频 ID。
  • 返回: 返回204 No Content,表示成功。

GetVideoMetaData

  • HTTP 方法: GET
  • 路由: meta/{id}
  • 功能: 获取视频的元数据(需要授权)。
  • 参数: 视频 ID。
  • 返回: 返回视频的元数据,支持缓存。

SetVideoScreenshot

  • HTTP 方法: PATCH
  • 路由: screenshot/{id}
  • 功能: 设置视频的缩略图(需要授权)。
  • 参数: 视频 ID 和一个 ScreenshotRequest 对象,包含截图的时间点。
  • 返回: 返回截图的 URL 或相关信息。

3. 错误处理

  • 控制器中的方法通过返回不同的 HTTP 状态码(如 200、204、400、404、401)来处理成功和错误情况,确保 API 的使用者能够清楚地了解请求的结果。

4. 总结

这个控制器提供了一系列与视频相关的 API 接口,包括获取视频列表、发送和获取弹幕、管理视频信息、增加播放次数、获取视频元数据和设置视频缩略图等功能,适用于视频播放和管理的应用场景。

loading