李昊 4 rokov pred
rodič
commit
2fae8cce53

+ 73 - 3
gx_api/GxPress/Api/GxPress.Api/WebControllers/WebMediaController.cs

@@ -1,5 +1,8 @@
+using System;
+using System.IO;
 using System.Threading.Tasks;
 using GxPress.Auth;
+using GxPress.Common.Exceptions;
 using GxPress.Repository.Interface.Media;
 using GxPress.Request.Media;
 using GxPress.Result.Media;
@@ -7,6 +10,8 @@ using GxPress.Service.Interface.Media;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.Net.Http.Headers;
 
 namespace GxPress.Api.WebControllers
 {
@@ -21,13 +26,17 @@ namespace GxPress.Api.WebControllers
         private readonly IMediaRepository mediaRepository;
         private readonly ILoginContext _loginContext;
         private readonly IMediaService mediaService;
-        private readonly IHttpContextAccessor httpContextAccessor;
-        public WebMediaController(IMediaRepository mediaRepository, ILoginContext _loginContext, IMediaService mediaService, IHttpContextAccessor httpContextAccessor)
+        private IHttpContextAccessor _contextAccessor;
+        private readonly IMediaLibraryRepository mediaLibraryRepository;
+        private HttpContext _context { get { return _contextAccessor.HttpContext; } }
+
+        public WebMediaController(IMediaRepository mediaRepository, ILoginContext _loginContext, IMediaService mediaService, IHttpContextAccessor contextAccessor, IMediaLibraryRepository mediaLibraryRepository)
         {
             this.mediaRepository = mediaRepository;
             this._loginContext = _loginContext;
             this.mediaService = mediaService;
-            this.httpContextAccessor = httpContextAccessor;
+            _contextAccessor = contextAccessor;
+            this.mediaLibraryRepository = mediaLibraryRepository;
         }
         /// <summary>
         /// 详情
@@ -53,6 +62,17 @@ namespace GxPress.Api.WebControllers
             return await mediaService.GetBookMediaResultAsync(id);
         }
         /// <summary>
+        /// 获取视频详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("video/{id}")]
+        [AllowAnonymous]
+        public async Task<VideoMediaResult> GetVideoMediaResultAsync(int id)
+        {
+            return await mediaService.GetVideoMediaResultAsync(id);
+        }
+        /// <summary>
         /// 获取章节内容
         /// </summary>
         /// <param name="request"></param>
@@ -63,5 +83,55 @@ namespace GxPress.Api.WebControllers
         {
             return await mediaService.GetBookMediaContentResultAsync(request);
         }
+
+        /// <summary>
+        /// 分页视频流
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [AllowAnonymous]
+        public async Task<IActionResult> GetVideo(VideoMediaFileStreamRequest request)
+        {
+            var range = Request.Headers["Range"].ToString().Replace("bytes=", "");
+            try
+            {
+                if (request.MediaLibraryId == 0)
+                    throw new BusinessException("不存在");
+                if (string.IsNullOrEmpty(range))
+                    throw new BusinessException("服务器异常");
+                //获取文件
+                var mediaLibrary = await mediaLibraryRepository.GetAsync(request.MediaLibraryId);
+                var filepath = "wwwroot" + mediaLibrary.FileUrl;
+                //var filepath = "http://localhost:83/cache/20200428/1588144602647614.mp4";
+                //从第3个到第12个字节,共10个字节。(0是第一个字节)
+                var begin = int.Parse(range.Split('-')[0]);
+                var end = int.Parse(range.Split('-')[1]);
+                var byteLength = (end - begin) + 1;
+                var bytes = new byte[byteLength];
+                //var fristBytes = new byte[1024];
+                FileInfo fileInfo = new FileInfo(filepath);
+                //获取后缀名
+                var ext = fileInfo.Extension;
+                new FileExtensionContentTypeProvider().Mappings.TryGetValue(ext, out var contenttype);
+                //获取文件流
+                StreamReader stream = new StreamReader(System.IO.File.OpenRead(filepath));
+                //stream.BaseStream.Read(fristBytes, 0, 1024);
+                stream.BaseStream.Seek(begin, SeekOrigin.Begin);
+                stream.BaseStream.Read(bytes, 0, byteLength);
+                stream.Close();
+                //var newBytes = new byte[fristBytes.Length + bytes.Length];
+                // fristBytes.CopyTo(newBytes, 0);
+                // bytes.CopyTo(newBytes, fristBytes.Length);
+                _context.Response.Headers.Add(HeaderNames.AcceptRanges, "bytes");
+                _context.Response.Headers.Add(HeaderNames.ContentRange, $"bytes {Request.Headers["Range"].ToString()}/{fileInfo.Length}");
+                _context.Response.StatusCode = 206;
+                var actionResult = File(bytes, contenttype ?? "application/octet-stream", fileInfo.Name);
+                return actionResult;
+            }
+            catch (Exception ex)
+            {
+                throw new BusinessException($"{ex.Message}");
+            }
+        }
     }
 }

+ 2 - 1
gx_api/GxPress/Model/GxPress.Mappings/MediaMapping.cs

@@ -15,7 +15,8 @@ namespace GxPress.Mappings
             CreateMap<MediaLibraryResult, MediaLibrary>();
             CreateMap<MediaLableResult, MediaLable>();
             CreateMap<MediaLable, MediaLableResult>();
-            CreateMap<Media,BookMediaResult>();
+            CreateMap<Media, BookMediaResult>();
+            CreateMap<Media, VideoMediaResult>();
         }
 
     }

+ 18 - 0
gx_api/GxPress/Model/GxPress.Request/Media/VideoMediaRequest.cs

@@ -0,0 +1,18 @@
+namespace GxPress.Request.Media
+{
+    public class VideoMediaRequest
+    {
+
+    }
+    /// <summary>
+    /// 获取文件流
+    /// </summary>
+    public class VideoMediaFileStreamRequest
+    {
+        /// <summary>
+        /// id
+        /// </summary>
+        /// <value></value>
+       public int MediaLibraryId{get;set;}
+    }
+}

+ 131 - 0
gx_api/GxPress/Model/GxPress.Result/Media/VideoMediaResult.cs

@@ -0,0 +1,131 @@
+using System.Collections.Generic;
+
+namespace GxPress.Result.Media
+{
+    /// <summary>
+    /// 视频
+    /// </summary>
+    public class VideoMediaResult
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        public int Id { get; set; }
+
+        /// <summary>
+        /// 媒体类型 文章100 书籍20,课程30,音频40,期刊50,视频60,名栏90,公众号110,刊期120
+        /// </summary>
+
+        public int MediaType { get; set; }
+        /// <summary>
+        /// 标题
+        /// </summary>
+
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 标题图片
+        /// </summary>
+
+        public string ImageUrls { get; set; }
+
+        /// <summary>
+        /// 简介
+        /// </summary>
+
+        public string Summary { get; set; }
+
+        /// <summary>
+        /// 作者
+        /// </summary>
+
+        public string Author { get; set; }
+
+        /// <summary>
+        /// 来源
+        /// </summary>
+
+        public string Source { get; set; }
+
+        /// <summary>
+        /// Json内容
+        /// </summary>
+        public string Blocks { get; set; }
+
+
+        /// <summary>
+        /// 添加时间
+        /// </summary>
+
+        public string AddDate { get; set; }
+
+        /// <summary>
+        /// 文章阅读量
+        /// </summary>
+
+        public int ReadCount { get; set; }
+
+        /// <summary>
+        /// 是否推荐 1 设置 2取消
+        /// </summary>
+
+        public int IsRecommend { get; set; }
+        /// <summary>
+        /// 出版社
+        /// </summary>
+
+        public string Press { get; set; }
+        /// <summary>
+        /// 出版时间
+        /// </summary>
+
+        public string PublishTime { get; set; }
+
+        /// <summary>
+        /// ios折扣价格打折
+        /// </summary>
+        public decimal IosDiscountPrice { get; set; }
+        /// <summary>
+        /// IOS价格
+        /// </summary>
+        public decimal IosPrice { get; set; }
+        /// <summary>
+        /// 其他折扣价格打折
+        /// </summary>
+        public decimal OtherDiscountPrice { get; set; }
+        /// <summary>
+        /// 其他价格
+        /// </summary>
+        public decimal OtherPrice { get; set; }
+        /// <summary>
+        /// 免费类容占比
+        /// </summary>
+        /// <value></value>
+        public decimal FreeProportion { get; set; }
+        /// <summary>
+        /// 收藏次数
+        /// </summary>
+        public int CollectCount { get; set; }
+        /// <summary>
+        /// 转发数量
+        /// </summary>
+        /// <value></value>
+        public int RetransmissionCount { get; set; }
+        /// <summary>
+        /// 评论数量
+        /// </summary>
+        /// <value></value>
+        public int CommentCount { get; set; }
+
+        /// <summary>
+        /// 视频
+        /// </summary>
+        /// <value></value>
+        public List<MediaLibraryResult> MediaLibraryResults { get; set; }
+        /// <summary>
+        /// 评论分数
+        /// </summary>
+        /// <value></value>
+        public decimal CommentScore { get; set; }
+    }
+}

+ 17 - 0
gx_api/GxPress/Repository/GxPress.Repository.Implement/Media/MediaLibraryRepository.cs

@@ -1,11 +1,13 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading.Tasks;
 using AutoMapper;
 using Datory;
 using GxPress.Common.AppOptions;
 using GxPress.Common.Tools;
 using GxPress.Repository.Interface.Media;
+using GxPress.Result.Media;
 using Microsoft.Extensions.Options;
 
 namespace GxPress.Repository.Implement.Media
@@ -35,5 +37,20 @@ namespace GxPress.Repository.Implement.Media
         {
             return await _repository.GetAsync(Q.Where(nameof(Entity.tede2.Media.MediaLibrary.MediaId), mediaId).Where(nameof(Entity.tede2.Media.MediaLibrary.TypeId), 1));
         }
+        public async Task<Entity.tede2.Media.MediaLibrary> GetAsync(int id)
+        {
+            return await _repository.GetAsync(id);
+        }
+        /// <summary>
+        /// 获取视频
+        /// </summary>
+        /// <param name="mediaId"></param>
+        /// <param name="TypeId"></param>
+        /// <returns></returns>
+        public async Task<List<MediaLibraryResult>> GetAllAsync(int mediaId)
+        {
+            var result = await _repository.GetAllAsync(Q.Select(nameof(Entity.tede2.Media.MediaLibrary.Id), nameof(Entity.tede2.Media.MediaLibrary.Name), nameof(Entity.tede2.Media.MediaLibrary.MediaId)).Where(nameof(Entity.tede2.Media.MediaLibrary.MediaId), mediaId).Where(nameof(Entity.tede2.Media.MediaLibrary.TypeId), 2));
+            return result.Select(n => _mapper.Map<MediaLibraryResult>(n)).ToList();
+        }
     }
 }

+ 10 - 0
gx_api/GxPress/Repository/GxPress.Repository.Implement/Media/MediaRepository.cs

@@ -350,5 +350,15 @@ namespace GxPress.Repository.Implement.Media
             var result = await _repository.GetAsync(Q.Where(nameof(Entity.tede2.Media.Media.Id), mediaId).Where(nameof(Entity.tede2.Media.Media.IsChecked), true).Where(nameof(Entity.tede2.Media.Media.IsDelete), false));
             return _mapper.Map<BookMediaResult>(result);
         }
+        /// <summary>
+        /// 获取视频
+        /// </summary>
+        /// <param name="mediaId"></param>
+        /// <returns></returns>
+        public async Task<VideoMediaResult> GetVideoMediaResultAsync(int mediaId)
+        {
+            var result = await _repository.GetAsync(Q.Where(nameof(Entity.tede2.Media.Media.Id), mediaId).Where(nameof(Entity.tede2.Media.Media.IsChecked), true).Where(nameof(Entity.tede2.Media.Media.IsDelete), false));
+            return _mapper.Map<VideoMediaResult>(result);
+        }
     }
 }

+ 12 - 1
gx_api/GxPress/Repository/GxPress.Repository.Interface/Media/IMediaLibraryRepository.cs

@@ -1,11 +1,22 @@
 using System;
+using System.Collections.Generic;
 using System.Threading.Tasks;
 using Datory;
+using GxPress.Result.Media;
 
 namespace GxPress.Repository.Interface.Media
 {
-    public interface IMediaLibraryRepository:IRepository
+    public interface IMediaLibraryRepository : IRepository
     {
         Task<Entity.tede2.Media.MediaLibrary> GetTaskAsync(int mediaId);
+        /// <summary>
+        /// 获取视频
+        /// </summary>
+        /// <param name="mediaId"></param>
+        /// <param name="TypeId"></param>
+        /// <returns></returns>
+        Task<List<MediaLibraryResult>> GetAllAsync(int mediaId);
+
+         Task<Entity.tede2.Media.MediaLibrary> GetAsync(int id);
     }
 }

+ 6 - 0
gx_api/GxPress/Repository/GxPress.Repository.Interface/Media/IMediaRepository.cs

@@ -35,5 +35,11 @@ namespace GxPress.Repository.Interface.Media
         /// <param name="mediaId"></param>
         /// <returns></returns>
         Task<BookMediaResult> GetBookMediaResultAsync(int mediaId);
+        /// <summary>
+        /// 获取书籍
+        /// </summary>
+        /// <param name="mediaId"></param>
+        /// <returns></returns>
+        Task<VideoMediaResult> GetVideoMediaResultAsync(int mediaId);
     }
 }

+ 16 - 0
gx_api/GxPress/Service/GxPress.Service.Implement/Media/MediaService.cs

@@ -78,6 +78,22 @@ namespace GxPress.Service.Implement.Media
             //书籍
             result.BookCatalogResults = epubService.GetCatalog("wwwroot" + mediaLibrary.FileUrl);
             //计算免费占比
+            return result;
+        }
+        /// <summary>
+        /// 获取视频详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task<VideoMediaResult> GetVideoMediaResultAsync(int id)
+        {
+            var result = await mediaRepository.GetVideoMediaResultAsync(id);
+            if (result == null)
+                throw new Common.Exceptions.BusinessException("不存在");
+            if (result.MediaType != GxPress.EnumConst.ResourceTypeConst.Video.GetHashCode())
+                throw new Common.Exceptions.BusinessException("非视频");
+            //获取视频
+            result.MediaLibraryResults = await mediaLibraryRepository.GetAllAsync(id);
 
             return result;
         }

+ 7 - 1
gx_api/GxPress/Service/GxPress.Service.Interface/Media/IMediaService.cs

@@ -20,6 +20,12 @@ namespace GxPress.Service.Interface.Media
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
-         Task<string> GetBookMediaContentResultAsync(BookCatalogRequest request);
+        Task<string> GetBookMediaContentResultAsync(BookCatalogRequest request);
+        /// <summary>
+        /// 获取视频详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        Task<VideoMediaResult> GetVideoMediaResultAsync(int id);
     }
 }