├── ZLMediaKit.HttpApi.Test ├── UnitTest1.cs ├── ZLMediaKit.HttpApi.Test.csproj └── WebHookEventTest.cs ├── ZLMediaKit.WebHook.Demo ├── appsettings.Development.json ├── appsettings.json ├── WeatherForecast.cs ├── ZLMediaKit.WebHook.Demo.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── Controllers │ └── WeatherForecastController.cs └── HookService.cs ├── ZLMediaKit.Common ├── Dtos │ ├── HookResultDto │ │ ├── IHookPlayResult.cs │ │ ├── IHookRecordMp4Result.cs │ │ ├── IHookRecordTsResult.cs │ │ ├── IHookReportFlowResult.cs │ │ ├── IHookShellLoginResult.cs │ │ ├── IHookServerStartedResult.cs │ │ ├── IHookStreamChangedResult.cs │ │ ├── IHookStreamNotFoundResult.cs │ │ ├── IHookServerKeepaliveResult.cs │ │ ├── IHookCommonResult.cs │ │ ├── IHookRtspRealmResult.cs │ │ ├── IHookStreamNonReaderResult.cs │ │ ├── IHookRtspAuthResult.cs │ │ ├── IHookPublishResult.cs │ │ └── IHookHttpAccessResult.cs │ ├── ApiInputDto │ │ ├── IApiGetMediaInfo.cs │ │ ├── IApiRestartServerResult.cs │ │ ├── IApiGetServerConfigResult.cs │ │ ├── IApiGetAllSessionResult.cs │ │ ├── IApiPauseRtpCheckResult.cs │ │ ├── IApiStopSendRtpResult.cs │ │ ├── IApiResumeRtpCheckResult.cs │ │ ├── IApiGetStatisticResult.cs │ │ ├── IApiGetMediaListResult.cs │ │ ├── IApiStartRecordResult.cs │ │ ├── IApiStopRecordResult.cs │ │ ├── IApiIsMediaOnlineResult.cs │ │ ├── IApiSeekRecordStampResult.cs │ │ ├── IApiSetRecordSpeedResult.cs │ │ ├── ISetServerConfigResult.cs │ │ ├── IApKillSessionsResult.cs │ │ ├── IApiCloseRtpServerResult.cs │ │ ├── IApiCloseStreamResult.cs │ │ ├── IApiIsRecordingResult.cs │ │ ├── IApiOpenRtpServerResult.cs │ │ ├── IApiStartSendRtpResult.cs │ │ ├── IApiDelStreamProxyResult.cs │ │ ├── IApiAddStreamPorxyResult.cs │ │ ├── IApiAddStreamPusherProxyResult.cs │ │ ├── IApiAddFFmpegSourceResult.cs │ │ ├── IApiDelFFmpegSourceResult.cs │ │ ├── IApiDelStreamPusherProxyResult.cs │ │ ├── IApiClonseStreamsResult.cs │ │ ├── ISetServerConfigInput.cs │ │ ├── IThreadsLoadApiResult.cs │ │ ├── IWorkThreadsLoadApiResult.cs │ │ ├── IApiGetMp4RecordFileResult.cs │ │ ├── IApiListRtpServerResult.cs │ │ ├── IApiGetRtpInfoResult.cs │ │ └── IApiResultBase.cs │ ├── HookInputDto │ │ ├── IRecordTsInput.cs │ │ ├── IPlayInput.cs │ │ ├── IPublishInput.cs │ │ ├── IStreamNoneReaderInput.cs │ │ ├── IRtspRealmInput.cs │ │ ├── IStreamNotFoundInuut.cs │ │ ├── IServerStartedInput.cs │ │ ├── IStreamChangedInput.cs │ │ ├── IShellLoginInput.cs │ │ ├── IServerKeepaliveInput.cs │ │ ├── IReportFlowInput.cs │ │ ├── IRtspAuthInput.cs │ │ ├── IHttpAccessInput.cs │ │ └── IRecordMp4Input.cs │ ├── IResultBase.cs │ ├── IEvnetBase.cs │ ├── MediaCodecEnum.cs │ ├── EventArgs │ │ └── IHookEventArgs.cs │ ├── IMediaBase.cs │ ├── ISocketInfo.cs │ ├── IKeepalive.cs │ ├── IHookBase.cs │ ├── IVideoMediaTrack.cs │ ├── IMediaInfo.cs │ └── IServerConfig.cs ├── OriginTypeEnum.cs ├── ZLMediaKit.Common.csproj ├── System │ └── Text │ │ └── Json │ │ └── Serialization │ │ ├── TypeMappingConvert.cs │ │ └── ZLBoolConverter.cs ├── IZLMediaKitSettings.cs ├── ServerManager.cs └── TypeMapping.cs ├── ZLMediaKit.WebHook ├── ZLMediaKitControllerFeatureProvider.cs ├── APIRouteOptions.cs ├── Microsoft │ └── Extensions │ │ └── DependencyInjection │ │ └── ZLMediaKitWebHookExtension.cs ├── ZLMediaKit.WebHook.csproj ├── ZLMediaKitWebHookApplicationModelConvention.cs ├── RegisteredModelInstance.cs ├── ZLMediaKitWebHookEvents.cs └── Services │ └── ZLMediaKitWebHookServcies.cs ├── LICENSE ├── ZLMediaKit.HttpApi ├── ZLHttpClientRegister.cs ├── ZLMediaKit.HttpApi.csproj └── Microsoft │ └── Extensions │ └── DependencyInjection │ └── ZLMediaKitHttpApiExtension.cs ├── ZLMediaKit.HttpApi.sln ├── README.md └── .gitignore /ZLMediaKit.HttpApi.Test/UnitTest1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chengxiaosheng/ZLMediaKit.HttpApi/HEAD/ZLMediaKit.HttpApi.Test/UnitTest1.cs -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookPlayResult.cs: -------------------------------------------------------------------------------- 1 | namespace ZLMediaKit.Common.Dtos.HookResultDto 2 | { 3 | public interface IHookPlayResult : IHookCommonResult 4 | { 5 | } 6 | 7 | public class HookPlayResult : HookCommonResult, IHookPlayResult 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookRecordMp4Result.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace ZLMediaKit.Common.Dtos.HookResultDto 3 | { 4 | public interface IHookRecordMp4Result : IHookCommonResult 5 | { 6 | } 7 | public class HookRecordMp4Result : HookCommonResult, IHookRecordMp4Result 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookRecordTsResult.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookResultDto 4 | { 5 | public interface IHookRecordTsResult : IHookCommonResult 6 | { 7 | } 8 | public class HookRecordTsResult:HookCommonResult , IHookRecordTsResult 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiGetMediaInfo.cs: -------------------------------------------------------------------------------- 1 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 2 | { 3 | public interface IApiGetMediaInfo: IApiResultBase 4 | { 5 | 6 | } 7 | 8 | public class ApiGetMediaInfo : ApiResultBase, IApiGetMediaInfo 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiRestartServerResult.cs: -------------------------------------------------------------------------------- 1 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 2 | { 3 | public interface IApiRestartServerResult : IApiResultBase 4 | { 5 | 6 | } 7 | 8 | public class ApiRestartServerResult : ApiResultBase , IApiRestartServerResult 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookReportFlowResult.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace ZLMediaKit.Common.Dtos.HookResultDto 3 | { 4 | public interface IHookReportFlowResult : IHookCommonResult 5 | { 6 | } 7 | 8 | public class HookReportFlowResult: HookCommonResult, IHookReportFlowResult 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookShellLoginResult.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookResultDto 4 | { 5 | public interface IHookShellLoginResult : IHookCommonResult 6 | { 7 | } 8 | 9 | public class HookShellLoginResult: HookCommonResult , IHookShellLoginResult 10 | { 11 | 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiGetServerConfigResult.cs: -------------------------------------------------------------------------------- 1 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 2 | { 3 | public interface IApiGetServerConfigResult: IApiResultBase 4 | { 5 | } 6 | public class ApiGetServerConfigResult : ApiResultBase, IApiGetServerConfigResult 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiGetAllSessionResult.cs: -------------------------------------------------------------------------------- 1 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 2 | { 3 | public interface IApiGetAllSessionResult : IApiResultListBase 4 | { 5 | 6 | } 7 | 8 | public class ApiGetAllSessionResult : ApiResultListBase, IApiGetAllSessionResult 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IRecordTsInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookInputDto 8 | { 9 | public interface IRecordTsInput : IRecordMp4Input { } 10 | 11 | public class RecordTsInput : RecordMp4Input, IRecordTsInput { } 12 | } 13 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ZLMediaKit.WebHook.Demo 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/ZLMediaKit.WebHook.Demo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiPauseRtpCheckResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 8 | { 9 | public interface IApiPauseRtpCheckResult : IApiResultBase 10 | { 11 | } 12 | 13 | public class ApiPauseRtpCheckResult : ApiResultBase, IApiPauseRtpCheckResult 14 | { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiStopSendRtpResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 8 | { 9 | public interface IApiStopSendRtpResult : IApiResultBase 10 | { 11 | 12 | } 13 | 14 | public class ApiStopSendRtpResult : ApiResultBase, IApiStopSendRtpResult 15 | { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiResumeRtpCheckResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 8 | { 9 | public interface IApiResumeRtpCheckResult : IApiResultBase 10 | { 11 | } 12 | 13 | public class ApiResumeRtpCheckResult : ApiResultBase , IApiResumeRtpCheckResult 14 | { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookServerStartedResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookResultDto 8 | { 9 | public interface IHookServerStartedResult : IHookCommonResult 10 | { 11 | } 12 | public class HookServerStartedResult: HookCommonResult, IHookServerStartedResult 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookStreamChangedResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookResultDto 8 | { 9 | public interface IHookStreamChangedResult : IHookCommonResult 10 | { 11 | } 12 | 13 | public class HookStreamChangedResult : HookCommonResult, IHookStreamChangedResult 14 | { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookStreamNotFoundResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookResultDto 8 | { 9 | public interface IHookStreamNotFoundResult : IHookCommonResult 10 | { 11 | } 12 | public class HookStreamNotFoundResult : HookCommonResult, IHookStreamNotFoundResult 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiGetStatisticResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 8 | { 9 | public interface IApiGetStatisticResult : IApiResultBase 10 | { 11 | 12 | } 13 | public class ApiGetStatisticResult : ApiResultBase, IApiGetStatisticResult 14 | { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookServerKeepaliveResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookResultDto 8 | { 9 | public interface IHookServerKeepaliveResult : IHookCommonResult 10 | { 11 | } 12 | 13 | public class HookServerKeepaliveResult : HookCommonResult, IHookServerKeepaliveResult 14 | { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiGetMediaListResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 8 | { 9 | public interface IApiGetMediaListResult : IApiResultListBase 10 | { 11 | 12 | } 13 | public class ApiGetMediaListResult : ApiResultListBase, IApiGetMediaListResult 14 | { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/OriginTypeEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common 8 | { 9 | public enum OriginTypeEnum 10 | { 11 | unknown = 0, 12 | rtmp_push = 1, 13 | rtsp_push = 2, 14 | rtp_push = 3, pull = 4, 15 | ffmpeg_pull = 5, 16 | mp4_vod = 6, 17 | device_chn = 7, 18 | rtc_push = 8 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IResultBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos 9 | { 10 | public interface IResultBase 11 | { 12 | [JsonPropertyName("code")] 13 | public int Code { get; set; } 14 | } 15 | 16 | public class ResultBase: IResultBase 17 | { 18 | 19 | [JsonPropertyName("code")] 20 | public virtual int Code { get; set; } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IPlayInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookInputDto 8 | { 9 | /// 10 | /// 播放器鉴权事件 11 | /// 12 | public interface IPlayInput : IHookInputWithMediaBaseAndClient 13 | { 14 | 15 | } 16 | 17 | /// 18 | /// 播放器鉴权事件 19 | /// 20 | public class PlayInput: HookWithMediaBaseAndClient , IPlayInput 21 | { 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/ZLMediaKitControllerFeatureProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Controllers; 2 | using System.Reflection; 3 | using ZLMediaKit.WebHook.Services; 4 | 5 | namespace ZLMediaKit.WebHook 6 | { 7 | internal class ZLMediaKitControllerFeatureProvider : ControllerFeatureProvider 8 | { 9 | protected override bool IsController(TypeInfo typeInfo) 10 | { 11 | if (typeInfo == typeof(ZLMediaKitWebHookServcies)) 12 | { 13 | return true; 14 | } 15 | return base.IsController(typeInfo); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IPublishInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookInputDto 8 | { 9 | /// 10 | /// rtsp/rtmp/rtp推流鉴权事 11 | /// 12 | public interface IPublishInput : IHookInputWithMediaBaseAndClient 13 | { 14 | 15 | } 16 | 17 | /// 18 | /// rtsp/rtmp/rtp推流鉴权事 19 | /// 20 | public class PublishInpu : HookWithMediaBaseAndClient, IPublishInput 21 | { 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IEvnetBase.cs: -------------------------------------------------------------------------------- 1 | namespace ZLMediaKit.Common.Dtos 2 | { 3 | public interface IEvnetBase 4 | { 5 | /// 6 | /// 服务器信息 7 | /// 8 | public IServerManager ServerManager { get; set; } 9 | 10 | 11 | } 12 | 13 | public class EvnetBase : IEvnetBase 14 | { 15 | public EvnetBase() { } 16 | public EvnetBase(IServerManager serverManager = null) 17 | { 18 | ServerManager = serverManager; 19 | } 20 | 21 | public IServerManager ServerManager { get; set; } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/ZLMediaKit.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5;net6 5 | True 6 | ./ZLMediaKit.Common.xml 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IStreamNoneReaderInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookInputDto 8 | { 9 | /// 10 | /// 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 11 | /// 12 | public interface IStreamNoneReaderInput : IHookInputWithMediaBase 13 | { 14 | } 15 | 16 | /// 17 | /// 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 18 | /// 19 | public class StreamNoneReaderInput :HookWithMediaBase, IStreamNoneReaderInput { } 20 | } 21 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/MediaCodecEnum.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace ZLMediaKit.Common.Dtos 4 | { 5 | public enum MediaCodecEnum 6 | { 7 | [Description("H264")] 8 | H264 = 0, 9 | [Description("H265")] 10 | H265 = 1, 11 | [Description("AAC")] 12 | AAC = 2, 13 | [Description("G711A")] 14 | G711A = 3, 15 | [Description("G711U")] 16 | G711U = 4 17 | } 18 | 19 | public enum MediaCodecTypeEnum 20 | { 21 | [Description("Video")] 22 | Video = 0, 23 | [Description("Audio")] 24 | Audio = 1, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IRtspRealmInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookInputDto 8 | { 9 | /// 10 | /// 该rtsp流是否开启rtsp专用方式的鉴权事件,开启后才会触发on_rtsp_auth事件 11 | /// 12 | public interface IRtspRealmInput : IHookInputWithMediaBaseAndClient 13 | { 14 | 15 | } 16 | 17 | /// 18 | /// 该rtsp流是否开启rtsp专用方式的鉴权事件,开启后才会触发on_rtsp_auth事件 19 | /// 20 | public class RtspRealmInput: HookWithMediaBaseAndClient, IRtspRealmInput { } 21 | } 22 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookCommonResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookResultDto 4 | { 5 | public interface IHookCommonResult : IResultBase 6 | { 7 | /// 8 | /// 返回消息 9 | /// 10 | [JsonPropertyName("msg")] 11 | public string Message { get; set; } 12 | } 13 | 14 | public class HookCommonResult : ResultBase, IHookCommonResult 15 | { 16 | /// 17 | /// 返回消息 18 | /// 19 | [JsonPropertyName("msg")] 20 | public string Message { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IStreamNotFoundInuut.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookInputDto 8 | { 9 | /// 10 | /// 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。 11 | /// 12 | public interface IStreamNotFoundInuut : IHookInputWithMediaBaseAndClient 13 | { 14 | } 15 | 16 | /// 17 | /// 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感。 18 | /// 19 | public class StreamNotFoundInuut :HookWithMediaBaseAndClient, IStreamNotFoundInuut { } 20 | } 21 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiStartRecordResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiStartRecordResult : IApiResultBase 6 | { 7 | /// 8 | /// 是否成功 9 | /// 10 | [JsonPropertyName("result")] 11 | public bool Result { get; set; } 12 | } 13 | public class ApiStartRecordResult : ApiResultBase, IApiStartRecordResult 14 | { 15 | /// 16 | /// 是否成功 17 | /// 18 | [JsonPropertyName("result")] 19 | public bool Result { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiStopRecordResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiStopRecordResult : IApiResultBase 6 | { 7 | /// 8 | /// 是否成功 9 | /// 10 | [JsonPropertyName("result")] 11 | public bool Result { get; set; } 12 | } 13 | 14 | public class ApiStopRecordResult: ApiResultBase, IApiStopRecordResult 15 | { 16 | /// 17 | /// 是否成功 18 | /// 19 | [JsonPropertyName("result")] 20 | public bool Result { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiIsMediaOnlineResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiIsMediaOnlineResult : IApiResultBase 6 | { 7 | /// 8 | /// 是否在线 9 | /// 10 | [JsonPropertyName("online")] 11 | public bool Online { get; set; } 12 | } 13 | 14 | public class ApiIsMediaOnlineResult : ApiResultBase, IApiIsMediaOnlineResult 15 | { 16 | /// 17 | /// 是否在线 18 | /// 19 | [JsonPropertyName("online")] 20 | public bool Online { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiSeekRecordStampResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiSeekRecordStampResult : IApiResultBase 6 | { 7 | /// 8 | /// 9 | /// 10 | [JsonPropertyName("result")] 11 | public int Result { get; set; } 12 | } 13 | 14 | public class ApiSeekRecordStampResult: ApiResultBase, IApiSeekRecordStampResult 15 | { 16 | /// 17 | /// 18 | /// 19 | [JsonPropertyName("result")] 20 | public int Result { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiSetRecordSpeedResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiSetRecordSpeedResult : IApiResultBase 6 | { 7 | /// 8 | /// 0 成功, -1 失败,-2 流不存在 9 | /// 10 | [JsonPropertyName("result")] 11 | public int Result { get; set; } 12 | } 13 | 14 | public class ApiSetRecordSpeedResult : ApiResultBase, IApiSetRecordSpeedResult 15 | { 16 | /// 0 成功, -1 失败,-2 流不存在 17 | /// 18 | [JsonPropertyName("result")] 19 | public int Result { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/ISetServerConfigResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface ISetServerConfigResult : IApiResultBase 6 | { 7 | /// 8 | /// 配置项变更个数 9 | /// 10 | [JsonPropertyName("changed")] 11 | public int Changed { get; set; } 12 | } 13 | 14 | public class SetServerConfigResult : ApiResultBase, ISetServerConfigResult 15 | { 16 | /// 17 | /// 配置项变更个数 18 | /// 19 | [JsonPropertyName("changed")] 20 | public int Changed { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApKillSessionsResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApKillSessionsResult : IApiResultBase 6 | { 7 | /// 8 | /// 筛选命中客户端个数 9 | /// 10 | [JsonPropertyName("count_hit")] 11 | public int CountHit { get; set; } 12 | } 13 | 14 | public class ApKillSessionsResult : ApiResultBase, IApKillSessionsResult 15 | { 16 | /// 17 | /// 筛选命中客户端个数 18 | /// 19 | [JsonPropertyName("count_hit")] 20 | public int CountHit { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiCloseRtpServerResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiCloseRtpServerResult : IApiResultBase 6 | { 7 | /// 8 | /// CloseRtpServer 9 | /// 10 | [JsonPropertyName("hit")] 11 | public int Hit { get; set; } 12 | } 13 | 14 | public class ApiCloseRtpServerResult : ApiResultBase, IApiCloseRtpServerResult 15 | { 16 | /// 17 | /// CloseRtpServer 18 | /// 19 | [JsonPropertyName("hit")] 20 | public int Hit { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiCloseStreamResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiCloseStreamResult : IApiResultBase 6 | { 7 | /// 8 | /// 0:成功,-1:关闭失败,-2:该流不存在 9 | /// 10 | [JsonPropertyName("result")] 11 | public int Result { get; set; } 12 | } 13 | 14 | public class ApiCloseStreamResult : ApiResultBase , IApiCloseStreamResult 15 | { 16 | /// 17 | /// 0:成功,-1:关闭失败,-2:该流不存在 18 | /// 19 | [JsonPropertyName("result")] 20 | public int Result { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiIsRecordingResult.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Text.Json.Serialization; 3 | 4 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 5 | { 6 | public interface IApiIsRecordingResult : IApiResultBase 7 | { 8 | /// 9 | /// false:未录制,true:正在录制 10 | /// 11 | [JsonPropertyName("status")] 12 | public bool Status { get; set; } 13 | } 14 | 15 | public class ApiIsRecordingResult : ApiResultBase, IApiIsRecordingResult 16 | { 17 | /// 18 | /// false:未录制,true:正在录制 19 | /// 20 | [JsonPropertyName("status")] 21 | public bool Status { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookRtspRealmResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookResultDto 4 | { 5 | public interface IHookRtspRealmResult : IResultBase 6 | { 7 | /// 8 | /// 该rtsp流是否需要rtsp专有鉴权,空字符串代码不需要鉴权 9 | /// 10 | [JsonPropertyName("realm")] 11 | public string Realm { get; set; } 12 | } 13 | 14 | public class HookRtspRealmResult : ResultBase, IHookRtspRealmResult 15 | { 16 | /// 17 | /// 该rtsp流是否需要rtsp专有鉴权,空字符串代码不需要鉴权 18 | /// 19 | [JsonPropertyName("realm")] 20 | public string Realm { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IServerStartedInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ZLMediaKit.Common.Dtos.HookInputDto 8 | { 9 | /// 10 | /// 服务器启动事件,可以用于监听服务器崩溃重启;此事件对回复不敏感。 11 | /// 12 | public interface IServerStartedInput : IServerConfig, IHookBase 13 | { 14 | } 15 | public class ServerStartedInput : ServerConfig, IServerStartedInput 16 | { 17 | public string MediaServerId { get; set; } 18 | 19 | public string ZlMediaKitAddress { get; set; } 20 | 21 | public int ZlMediaKitPort { get; set; } 22 | 23 | public IHookBase Clone() => this.MemberwiseClone() as IHookBase; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IStreamChangedInput.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookInputDto 4 | { 5 | /// 6 | /// rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 7 | /// 8 | public interface IStreamChangedInput : IHookBase, IMediaInfo 9 | { 10 | 11 | } 12 | 13 | /// 14 | /// rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 15 | /// 16 | public class StreamChangedInput : MediaInfo, IStreamChangedInput 17 | { 18 | public string MediaServerId { get; set; } 19 | 20 | public string ZlMediaKitAddress { get; set; } 21 | 22 | public int ZlMediaKitPort { get; set; } 23 | 24 | public IHookBase Clone() => this.MemberwiseClone() as StreamChangedInput; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiOpenRtpServerResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiOpenRtpServerResult : IApiResultBase 11 | { 12 | /// 13 | /// 接收端口,方便获取随机端口号 14 | /// 15 | [JsonPropertyName("port")] 16 | public int Port { get; set; } 17 | } 18 | 19 | public class ApiOpenRtpServerResult : ApiResultBase, IApiOpenRtpServerResult 20 | { 21 | /// 22 | /// 接收端口,方便获取随机端口号 23 | /// 24 | [JsonPropertyName("port")] 25 | public int Port { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiStartSendRtpResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiStartSendRtpResult : IApiResultBase 11 | { 12 | /// 13 | /// 使用的本地端口号 14 | /// 15 | [JsonPropertyName("local_port")] 16 | public int LocalPort { get; set; } 17 | } 18 | 19 | public class ApiStartSendRtpResult : ApiResultBase, IApiStartSendRtpResult 20 | { 21 | /// 22 | /// 使用的本地端口号 23 | /// 24 | [JsonPropertyName("local_port")] 25 | public int LocalPort { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookStreamNonReaderResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.HookResultDto 9 | { 10 | public interface IHookStreamNonReaderResult : IResultBase 11 | { 12 | /// 13 | /// 是否关闭推流或拉流 14 | /// 15 | [JsonPropertyName("close")] 16 | public bool Close { get; set; } 17 | } 18 | 19 | public class HookStreamNonReaderResult : ResultBase, IHookStreamNonReaderResult 20 | { 21 | /// 22 | /// 是否关闭推流或拉流 23 | /// 24 | [JsonPropertyName("close")] 25 | public bool Close { get; set; } = true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace ZLMediaKit.WebHook.Demo 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IShellLoginInput.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookInputDto 4 | { 5 | /// 6 | /// shell登录鉴权 7 | /// 8 | public interface IShellLoginInput : IHookInputWithClient 9 | { 10 | /// 11 | /// telnet 终端登录用户密码 12 | /// 13 | [JsonPropertyName("passwd")] 14 | public string Password { get; } 15 | /// 16 | /// 用户名 17 | /// 18 | [JsonPropertyName("user_name")] 19 | public string Username { get; } 20 | } 21 | 22 | public class ShellLoginInput : HookInputWithClient, IShellLoginInput 23 | { 24 | public string Password { get; set; } 25 | 26 | public string Username { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ZLMediaKit.HttpApi.Test/ZLMediaKit.HttpApi.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IServerKeepaliveInput.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookInputDto 4 | { 5 | /// 6 | /// 服务器定时上报时间,上报间隔可配置,默认10s上报一次 7 | /// 8 | public interface IServerKeepaliveInput : IHookBase,IKeepalive 9 | { 10 | [JsonPropertyName("data")] 11 | public IKeepalive Data { get; } 12 | } 13 | 14 | /// 15 | /// 服务器定时上报时间,上报间隔可配置,默认10s上报一次 16 | /// 17 | public class ServerKeepaliveInput : Keepalive, IServerKeepaliveInput 18 | { 19 | public IKeepalive Data { get; set; } 20 | 21 | public string MediaServerId { get; set; } 22 | 23 | public string ZlMediaKitAddress { get; set; } 24 | 25 | public int ZlMediaKitPort { get; set; } 26 | 27 | public virtual IHookBase Clone() => this.MemberwiseClone() as ServerKeepaliveInput; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiDelStreamProxyResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiDelStreamProxyResultItem : IApiResultDataBase 6 | { 7 | /// 8 | /// 成功与否 9 | /// 10 | [JsonPropertyName("flag")] 11 | public bool Flag { get; set; } 12 | } 13 | public interface IApiDelStreamProxyResult : IApiResultBase 14 | { 15 | 16 | } 17 | 18 | public class ApiDelStreamProxyResultItem : IApiDelStreamProxyResultItem 19 | { 20 | /// 21 | /// 成功与否 22 | /// 23 | [JsonPropertyName("flag")] 24 | public bool Flag { get; set; } 25 | } 26 | 27 | public class ApiDelStreamProxyResult :ApiResultBase, IApiDelStreamProxyResult 28 | { 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:60760", 8 | "sslPort": 44350 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "ZLMediaKit.WebHook.Demo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "http://localhost:5001", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiAddStreamPorxyResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiAddStreamProxyResultItem : IApiResultDataBase 6 | { 7 | /// 8 | /// 流的唯一标识 9 | /// 10 | [JsonPropertyName("key")] 11 | public string Key { get; set; } 12 | } 13 | 14 | public interface IApiAddStreamPorxyResult : IApiResultBase 15 | { 16 | 17 | } 18 | public class ApiAddStreamProxyResultItem : IApiAddStreamProxyResultItem 19 | { 20 | /// 21 | /// 流的唯一标识 22 | /// 23 | [JsonPropertyName("key")] 24 | public string Key { get; set; } 25 | } 26 | 27 | public class ApiAddStreamPorxyResult: ApiResultBase, IApiAddStreamPorxyResult 28 | { 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiAddStreamPusherProxyResult.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Text.Json.Serialization; 3 | 4 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 5 | { 6 | public interface IApiAddStreamPusherProxyResultItem : IApiResultDataBase 7 | { 8 | /// 9 | /// 流的唯一标识 10 | /// 11 | [JsonPropertyName("key")] 12 | public string Key { get; set; } 13 | } 14 | 15 | public interface IApiAddStreamPusherProxyResult : IApiResultBase 16 | { 17 | 18 | } 19 | 20 | public class ApiAddStreamPusherProxyResultItem: IApiAddStreamPusherProxyResultItem 21 | { 22 | /// 23 | /// 流的唯一标识 24 | /// 25 | [JsonPropertyName("key")] 26 | public string Key { get; set; } 27 | } 28 | 29 | public class ApiAddStreamPusherProxyResult: ApiResultBase, IApiAddStreamPusherProxyResult 30 | { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/APIRouteOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ZLMediaKit.WebHook 4 | { 5 | /// 6 | /// 路由配置 7 | /// 8 | public class APIRouteOptions 9 | { 10 | /// 11 | /// 默认路由 12 | /// 13 | public const string DefaultRoutePrefix = "index/hook"; 14 | 15 | /// 16 | /// 路由 17 | /// 18 | /// action 之前的所有路径 19 | public string RoutePrefix { get; set; } 20 | 21 | /// 22 | /// api路由选项 23 | /// 24 | /// 25 | public APIRouteOptions(string routePrefix = DefaultRoutePrefix/*, string corsPolicyName = null*/) 26 | { 27 | RoutePrefix = routePrefix ?? throw new ArgumentNullException(nameof(routePrefix)); 28 | //CorsPolicyName = corsPolicyName;//?? throw new ArgumentNullException(nameof(corsPolicyName)); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/EventArgs/IHookEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | 3 | namespace ZLMediaKit.Common.Dtos.EventArgs 4 | { 5 | public interface IHookEventArgs :IEvnetBase where T:IHookBase 6 | { 7 | public HttpContext HttpContext { get; set; } 8 | 9 | /// 10 | /// 事件承载数据 11 | /// 12 | public T Payload { get; set; } 13 | } 14 | 15 | public class HookEventArgs : EvnetBase, IHookEventArgs where T : IHookBase 16 | { 17 | public HookEventArgs(HttpContext http, T payload) : base(IServerManager.GetServerManager(payload.MediaServerId)) 18 | { 19 | this.HttpContext = http; 20 | this.Payload = payload; 21 | } 22 | /// 23 | /// Http 数据 24 | /// 25 | public HttpContext HttpContext { get; set; } 26 | 27 | /// 28 | /// 事件承载数据 29 | /// 30 | public T Payload { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookRtspAuthResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookResultDto 4 | { 5 | public interface IHookRtspAuthResult : IHookCommonResult 6 | { 7 | /// 8 | /// 用户密码是否已加密 9 | /// 10 | [JsonPropertyName("encrypted")] 11 | public bool Encrypted { get; set; } 12 | 13 | /// 14 | /// 用户密码 15 | /// 16 | [JsonPropertyName("passwd")] 17 | public string Passwd { get; set; } 18 | } 19 | 20 | public class HookRtspAuthResult : HookCommonResult, IHookRtspAuthResult 21 | { 22 | /// 23 | /// 用户密码是否已加密 24 | /// 25 | [JsonPropertyName("encrypted")] 26 | public bool Encrypted { get; set; } = false; 27 | 28 | /// 29 | /// 用户密码 30 | /// 31 | [JsonPropertyName("passwd")] 32 | public string Passwd { get; set; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/System/Text/Json/Serialization/TypeMappingConvert.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using ZLMediaKit.Common; 3 | 4 | namespace System.Text.Json.Serialization 5 | { 6 | public class TypeMappingConvert : JsonConverter where TImplenetation :TType, new() 7 | { 8 | [return: MaybeNull] 9 | public override TType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 10 | { 11 | TypeMapping.TypeMappings.TryGetValue(typeof(TType), out var newType); 12 | if(newType != null) 13 | { 14 | return (TType)JsonSerializer.Deserialize(ref reader, newType, options); 15 | } 16 | return JsonSerializer.Deserialize(ref reader, options); 17 | } 18 | 19 | public override void Write(Utf8JsonWriter writer, TType value, JsonSerializerOptions options) 20 | { 21 | JsonSerializer.Serialize(writer, value, options); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiAddFFmpegSourceResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiAddFFmpegSourceResultItem : IApiResultDataBase 11 | { 12 | /// 13 | /// 流的唯一标识 14 | /// 15 | [JsonPropertyName("key")] 16 | public string Key { get; set; } 17 | } 18 | public interface IApiAddFFmpegSourceResult: IApiResultBase 19 | { 20 | } 21 | public class ApiAddFFmpegSourceResultItem : IApiAddFFmpegSourceResultItem 22 | { 23 | /// 24 | /// 流的唯一标识 25 | /// 26 | [JsonPropertyName("key")] 27 | public string Key { get; set; } 28 | } 29 | 30 | public class ApiAddFFmpegSourceResult : ApiResultBase, IApiAddFFmpegSourceResult 31 | { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiDelFFmpegSourceResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiDelFFmpegSourceResultItem : IApiResultDataBase 11 | { 12 | /// 13 | /// 成功与否 14 | /// 15 | [JsonPropertyName("flag")] 16 | public bool Flag { get; set; } 17 | } 18 | public interface IApiDelFFmpegSourceResult : IApiResultBase 19 | { 20 | 21 | } 22 | 23 | public class ApiDelFFmpegSourceResultItem : IApiDelFFmpegSourceResultItem 24 | { 25 | /// 26 | /// 成功与否 27 | /// 28 | [JsonPropertyName("flag")] 29 | public bool Flag { get; set; } 30 | } 31 | 32 | public class ApiDelFFmpegSourceResult: ApiResultBase, IApiDelFFmpegSourceResult 33 | { 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IReportFlowInput.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookInputDto 4 | { 5 | /// 6 | /// 流量统计事件 7 | /// 8 | public interface IReportFlowInput : IHookInputWithMediaBaseAndClient 9 | { 10 | /// 11 | /// tcp链接维持时间,单位秒 12 | /// 13 | [JsonPropertyName("duration")] 14 | public int Duration { get; set; } 15 | 16 | /// 17 | /// true为播放器,false为推流器 18 | /// 19 | [JsonPropertyName("player")] 20 | public bool Player { get; set; } 21 | 22 | /// 23 | /// 耗费上下行流量总和,单位字节 24 | /// 25 | [JsonPropertyName("totalBytes")] 26 | public int TotalBytes { get; set; } 27 | } 28 | 29 | public class ReportFlowInput : HookWithMediaBaseAndClient, IReportFlowInput 30 | { 31 | public int Duration { get; set; } 32 | 33 | public bool Player { get; set; } 34 | 35 | public int TotalBytes { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IMediaBase.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos 4 | { 5 | public interface IMediaBase 6 | { 7 | /// 8 | /// 流虚拟主机 9 | /// 10 | [JsonPropertyName("vhost")] 11 | public string Vhost { get; set; } 12 | /// 13 | /// 流应用名 14 | /// 15 | [JsonPropertyName("app")] 16 | public string App { get; set; } 17 | /// 18 | /// 播放或推流的协议,可能是rtsp、rtmp、http 19 | /// 20 | [JsonPropertyName("schema")] 21 | public string Schema { get; set; } 22 | /// 23 | /// 流ID 24 | /// 25 | [JsonPropertyName("stream")] 26 | public string Stream { get; set; } 27 | } 28 | 29 | public class MediaBase : IMediaBase 30 | { 31 | public string Vhost { get; set; } 32 | 33 | public string App { get; set; } 34 | 35 | public string Schema { get; set; } 36 | 37 | public string Stream { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiDelStreamPusherProxyResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiDelStreamPusherProxyResultItem : IApiResultDataBase 11 | { 12 | /// 13 | /// 成功与否 14 | /// 15 | [JsonPropertyName("flag")] 16 | public bool Flag { get; set; } 17 | } 18 | public interface IApiDelStreamPusherProxyResult : IApiResultBase 19 | { 20 | 21 | } 22 | public class ApiDelStreamPusherProxyResultItem : IApiDelStreamPusherProxyResultItem 23 | { 24 | /// 25 | /// 成功与否 26 | /// 27 | [JsonPropertyName("flag")] 28 | public bool Flag { get; set; } 29 | } 30 | 31 | public class ApiDelStreamPusherProxyResult : ApiResultBase, IApiDelStreamPusherProxyResult 32 | { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 ChengXiaosheng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/Microsoft/Extensions/DependencyInjection/ZLMediaKitWebHookExtension.cs: -------------------------------------------------------------------------------- 1 | using ZLMediaKit.WebHook; 2 | using ZLMediaKit.WebHook.Services; 3 | 4 | namespace Microsoft.Extensions.DependencyInjection 5 | { 6 | /// 7 | /// 8 | /// 9 | public static class ZLMediaKitWebHookExtension 10 | { 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static IServiceCollection AddMediaKitWebHook(this IServiceCollection services, APIRouteOptions routeOptions) 18 | { 19 | services.AddHttpContextAccessor(); 20 | 21 | services.AddTransient(); 22 | services.AddMvcCore(options => 23 | { 24 | options.Conventions.Add(new ZLMediaKitWebHookApplicationModelConvention(routeOptions)); 25 | 26 | }).PartManager.FeatureProviders.Add(new ZLMediaKitControllerFeatureProvider()); 27 | 28 | return services; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookPublishResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.HookResultDto 9 | { 10 | public interface IHookPublishResult : IHookCommonResult 11 | { 12 | /// 13 | /// 是否转换成hls协议 14 | /// 15 | [JsonPropertyName("enableHls")] 16 | public bool EnableHls { get; set; } 17 | 18 | /// 19 | /// 是否允许mp4录制 20 | /// 21 | [JsonPropertyName("enableMP4")] 22 | public bool EnableMP4 { get; set; } 23 | } 24 | 25 | public class HookPublishResult : HookCommonResult, IHookPublishResult 26 | { 27 | /// 28 | /// 是否转换成hls协议 29 | /// 30 | [JsonPropertyName("enableHls")] 31 | public bool EnableHls { get; set; } = false; 32 | 33 | /// 34 | /// 是否允许mp4录制 35 | /// 36 | [JsonPropertyName("enableMP4")] 37 | public bool EnableMP4 { get; set; } = false; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiClonseStreamsResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiClonseStreamsResult : IApiResultBase 11 | { 12 | /// 13 | /// 筛选条件命中数 14 | /// 15 | [JsonPropertyName("count_hit")] 16 | public int CountHit { get; set; } 17 | 18 | /// 19 | /// 被关闭的流个数,可能小于count_hit 20 | /// 21 | [JsonPropertyName("count_closed")] 22 | public int CountClose { get; set; } 23 | } 24 | 25 | public class ApiClonseStreamsResult : ApiResultBase, IApiClonseStreamsResult 26 | { 27 | /// 28 | /// 筛选条件命中数 29 | /// 30 | [JsonPropertyName("count_hit")] 31 | public int CountHit { get; set; } 32 | 33 | /// 34 | /// 被关闭的流个数,可能小于count_hit 35 | /// 36 | [JsonPropertyName("count_closed")] 37 | public int CountClose { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ZLMediaKit.HttpApi/ZLHttpClientRegister.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using ZLMediaKit.Common; 6 | 7 | namespace ZLMediaKit.HttpApi 8 | { 9 | /// 10 | /// 11 | /// 12 | public static class ZLHttpClientRegister 13 | { 14 | /// 15 | /// ZLMediaKit Client 注册 16 | /// 17 | /// 18 | public static void Register(ZLMediaKitSettings zLMediaKitSettings) 19 | { 20 | if (zLMediaKitSettings == null) throw new InvalidDataException("ZLMediaKitSettings 不能为空"); 21 | if (string.IsNullOrEmpty(zLMediaKitSettings.IpAddress)) throw new InvalidDataException("IpAddress 不能为空"); 22 | if (zLMediaKitSettings.ApiPort == 0) throw new InvalidDataException("ApiPort 参数值错误"); 23 | if (string.IsNullOrEmpty(zLMediaKitSettings.MediaServerId)) throw new InvalidDataException("MediaServerId 不能为空"); 24 | if (string.IsNullOrEmpty(zLMediaKitSettings.ApiSecret)) throw new InvalidDataException("ApiSecret 不能为空"); 25 | IServerManager.AddServer(zLMediaKitSettings); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/ISetServerConfigInput.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface ISetServerConfigInput 6 | { 7 | /// 8 | /// Config.ini 中的 [] 节点名称 9 | /// 如 api.apiDebug , 此处填写 api 10 | /// 11 | public string ClassName { get; set; } 12 | 13 | /// 14 | /// 具体配置项 15 | /// 如 api.apiDebug , 此处填写 apiDebug 16 | /// 17 | public string Key { get; set; } 18 | 19 | /// 20 | /// 配置值 如 0 21 | /// 22 | public object Value { get; set; } 23 | } 24 | 25 | public class SetServerConfigInput : ISetServerConfigInput 26 | { 27 | /// 28 | /// Config.ini 中的 [] 节点名称 29 | /// 如 api.apiDebug , 此处填写 api 30 | /// 31 | public string ClassName { get; set; } 32 | 33 | /// 34 | /// 具体配置项 35 | /// 如 api.apiDebug , 此处填写 apiDebug 36 | /// 37 | public string Key { get; set; } 38 | 39 | /// 40 | /// 配置值 如 0 41 | /// 42 | public object Value { get; set; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IThreadsLoadApiResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IThreadsLoadApiResultItem : IApiResultDataBase 6 | { 7 | /// 8 | /// 该线程延时 9 | /// 10 | [JsonPropertyName("delay")] 11 | public int Delay { get; set; } 12 | 13 | /// 14 | /// 该线程负载,0 ~ 100 15 | /// 16 | [JsonPropertyName("load")] 17 | public byte Load { get; set; } 18 | } 19 | 20 | public interface IThreadsLoadApiResult : IApiResultListBase 21 | { 22 | 23 | } 24 | 25 | public class ThreadsLoadApiResultItem : IThreadsLoadApiResultItem 26 | { 27 | /// 28 | /// 该线程延时 29 | /// 30 | [JsonPropertyName("delay")] 31 | public int Delay { get; set; } 32 | 33 | /// 34 | /// 该线程负载,0 ~ 100 35 | /// 36 | [JsonPropertyName("load")] 37 | public byte Load { get; set; } 38 | } 39 | 40 | public class ThreadsLoadApiResult : ApiResultListBase , IThreadsLoadApiResult 41 | { 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IWorkThreadsLoadApiResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IWorkThreadsLoadApiResultItem : IApiResultDataBase 6 | { 7 | /// 8 | /// 该线程延时 9 | /// 10 | [JsonPropertyName("delay")] 11 | public int Delay { get; set; } 12 | 13 | /// 14 | /// 该线程负载,0 ~ 100 15 | /// 16 | [JsonPropertyName("load")] 17 | public byte Load { get; set; } 18 | } 19 | 20 | public interface IWorkThreadsLoadApiResult : IApiResultListBase 21 | { 22 | 23 | } 24 | 25 | public class WorkThreadsLoadApiResultItem : IWorkThreadsLoadApiResultItem 26 | { 27 | /// 28 | /// 该线程延时 29 | /// 30 | [JsonPropertyName("delay")] 31 | public int Delay { get; set; } 32 | 33 | /// 34 | /// 该线程负载,0 ~ 100 35 | /// 36 | [JsonPropertyName("load")] 37 | public byte Load { get; set; } 38 | } 39 | public class WorkThreadsLoadApiResult : ApiResultListBase, IWorkThreadsLoadApiResult 40 | { 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IRtspAuthInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.HookInputDto 9 | { 10 | /// 11 | /// rtsp专用的鉴权事件,先触发on_rtsp_realm事件然后才会触发on_rtsp_auth事件 12 | /// 13 | public interface IRtspAuthInput : IHookInputWithMediaBaseAndClient 14 | { 15 | /// 16 | /// 请求的密码是否必须为明文(base64鉴权需要明文密码) 17 | /// 18 | [JsonPropertyName("must_no_encrypt")] 19 | public bool MustNoEncrypt { get; set; } 20 | 21 | /// 22 | /// rtsp播放鉴权加密realm 23 | /// 24 | [JsonPropertyName("realm")] 25 | public string Realm { get; set; } 26 | 27 | /// 28 | /// 播放用户名 29 | /// 30 | [JsonPropertyName("user_name")] 31 | public string UserName { get; set; } 32 | } 33 | 34 | /// 35 | /// rtsp专用的鉴权事件,先触发on_rtsp_realm事件然后才会触发on_rtsp_auth事件 36 | /// 37 | public class RtspAuthInput : HookWithMediaBaseAndClient, IRtspAuthInput 38 | { 39 | public bool MustNoEncrypt { get; set; } 40 | 41 | public string Realm { get; set; } 42 | 43 | public string UserName { get; set; } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiGetMp4RecordFileResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiGetMp4RecordFileResultItem : IApiResultDataBase 11 | { 12 | /// 13 | /// 14 | /// 15 | [JsonPropertyName("paths")] 16 | public IList Paths { get; set; } 17 | 18 | /// 19 | /// 20 | /// 21 | [JsonPropertyName("rootPath")] 22 | public string RootPath { get; set; } 23 | } 24 | 25 | public interface IApiGetMp4RecordFileResult : IApiResultListBase 26 | { 27 | 28 | } 29 | 30 | public class ApiGetMp4RecordFileResultItem : IApiGetMp4RecordFileResultItem 31 | { 32 | /// 33 | /// 34 | [JsonPropertyName("paths")] 35 | public IList Paths { get; set; } 36 | 37 | /// 38 | /// 39 | /// 40 | [JsonPropertyName("rootPath")] 41 | public string RootPath { get; set; } 42 | } 43 | 44 | public class ApiGetMp4RecordFileResult : ApiResultListBase, IApiGetMp4RecordFileResult 45 | { 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiListRtpServerResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json.Serialization; 6 | using System.Threading.Tasks; 7 | 8 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 9 | { 10 | public interface IApiListRtpServerResultItem : IApiResultDataBase 11 | { 12 | /// 13 | /// 绑定的端口号 14 | /// 15 | [JsonPropertyName("port")] 16 | public int Port { get; set; } 17 | 18 | /// 19 | /// 绑定的流ID 20 | /// 21 | [JsonPropertyName("stream_id")] 22 | public string StreamId { get; set; } 23 | } 24 | public interface IApiListRtpServerResult : IApiResultListBase 25 | { 26 | 27 | } 28 | 29 | public class ApiListRtpServerResultItem : IApiListRtpServerResultItem 30 | { 31 | /// 32 | /// 绑定的端口号 33 | /// 34 | [JsonPropertyName("port")] 35 | public int Port { get; set; } 36 | 37 | /// 38 | /// 绑定的流ID 39 | /// 40 | [JsonPropertyName("stream_id")] 41 | public string StreamId { get; set; } 42 | } 43 | 44 | public class ApiListRtpServerResult : ApiResultListBase, IApiListRtpServerResult 45 | { 46 | 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IHttpAccessInput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text.Json.Serialization; 5 | 6 | namespace ZLMediaKit.Common.Dtos.HookInputDto 7 | { 8 | /// 9 | /// http 访问路径是文件还是目录 10 | /// 11 | public interface IHttpAccessInput : IHookInputWithClient 12 | { 13 | /// 14 | /// http 访问路径是文件还是目录 15 | /// 16 | [JsonPropertyName("is_dir")] 17 | public bool IsDir { get; set; } 18 | /// 19 | /// 请求访问的文件或目录 20 | /// 21 | [JsonPropertyName("path")] 22 | public string Path { get; set; } 23 | /// 24 | /// http header 25 | /// 26 | public Dictionary Headers { get; set; } 27 | 28 | void InitHeader(Dictionary form); 29 | } 30 | 31 | /// 32 | /// http 访问路径是文件还是目录 33 | /// 34 | public class HttpAccessInput : HookInputWithClient, IHttpAccessInput 35 | { 36 | public bool IsDir { get; set; } 37 | 38 | public string Path { get; set; } 39 | 40 | public Dictionary Headers { get; set; } 41 | 42 | public void InitHeader(Dictionary form) 43 | { 44 | this.Headers = form.Select(s => new { Key = s.Key.Replace("header.", String.Empty, StringComparison.OrdinalIgnoreCase), Value = s.Value }).ToDictionary(s => s.Key, v => v.Value); 45 | } 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/IZLMediaKitSettings.cs: -------------------------------------------------------------------------------- 1 | public interface IZLMediaKitSettings 2 | { 3 | 4 | /// 5 | /// ip地址 6 | /// 7 | public string IpAddress { get; set; } 8 | /// 9 | /// api 端口 10 | /// 11 | /// 12 | public int ApiPort { get; set; } 13 | /// 14 | /// 密钥 15 | /// 16 | /// 17 | public string ApiSecret { get; set; } 18 | /// 19 | /// api 秦艽超时时间 20 | /// 21 | /// 22 | public int Timeout { get; set; } 23 | /// 24 | /// 服务唯一编码 25 | /// 26 | /// 27 | public string MediaServerId { get; set; } 28 | /// 29 | /// api 请求模式, http / https 30 | /// 31 | /// 32 | public HttpSchema HttpSchema { get; set; } 33 | 34 | public string ApiBaseUri { get; } 35 | } 36 | 37 | /// 38 | /// 基本配置 39 | /// 40 | public class ZLMediaKitSettings : IZLMediaKitSettings 41 | { 42 | public string IpAddress { get; set; } 43 | public int ApiPort { get; set; } 44 | public string ApiSecret { get; set; } = "035c73f7-bb6b-4889-a715-d9eb2d1925cc"; 45 | public int Timeout { get; set; } = 2000; 46 | public string MediaServerId { get; set; } = "your_server_id"; 47 | public HttpSchema HttpSchema { get; set; } = HttpSchema.Http; 48 | 49 | public string ApiBaseUri => $"{HttpSchema.ToString()}://{this.IpAddress}:{this.ApiPort}/index/api"; 50 | } 51 | 52 | 53 | /// 54 | /// http 请求模式 55 | /// 56 | public enum HttpSchema : byte 57 | { 58 | Http, 59 | Https 60 | } -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookResultDto/IHookHttpAccessResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookResultDto 4 | { 5 | /// 6 | /// 访问http文件服务器上hls之外的文件的返回结果 7 | /// 8 | public interface IHookHttpAccessResult : IResultBase 9 | { 10 | /// 11 | /// 不允许访问的错误提示,允许访问请置空 12 | /// 13 | [JsonPropertyName("err")] 14 | public string Message { get; set; } 15 | 16 | /// 17 | /// 该客户端能访问或被禁止的顶端目录,如果为空字符串,则表述为当前目录 18 | /// 19 | [JsonPropertyName("path")] 20 | public string Path { get; set; } 21 | 22 | /// 23 | /// 本次授权结果的有效期,单位秒 24 | /// 25 | [JsonPropertyName("second")] 26 | public int Second { get; set; } 27 | 28 | } 29 | /// 30 | /// 访问http文件服务器上hls之外的文件的返回结果 31 | /// 32 | public class HookHttpAccessResult : ResultBase, IHookHttpAccessResult 33 | { 34 | /// 35 | /// 请固定返回0 36 | /// 37 | [JsonPropertyName("code")] 38 | public override int Code => 0; 39 | 40 | /// 41 | /// 不允许访问的错误提示,允许访问请置空 42 | /// 43 | [JsonPropertyName("err")] 44 | public string Message { get; set; } 45 | 46 | /// 47 | /// 该客户端能访问或被禁止的顶端目录,如果为空字符串,则表述为当前目录 48 | /// 49 | [JsonPropertyName("path")] 50 | public string Path { get; set; } = ""; 51 | 52 | /// 53 | /// 本次授权结果的有效期,单位秒 54 | /// 55 | [JsonPropertyName("second")] 56 | public int Second { get; set; } = 600; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/System/Text/Json/Serialization/ZLBoolConverter.cs: -------------------------------------------------------------------------------- 1 | namespace System.Text.Json.Serialization 2 | { 3 | public class ZLBoolConverter : JsonConverter 4 | { 5 | public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 6 | { 7 | switch (reader.TokenType) 8 | { 9 | case JsonTokenType.None: 10 | return false; 11 | case JsonTokenType.StartObject: 12 | return false; 13 | case JsonTokenType.EndObject: 14 | return false; 15 | case JsonTokenType.StartArray: 16 | return false; 17 | case JsonTokenType.EndArray: 18 | return false; 19 | case JsonTokenType.PropertyName: 20 | return false; 21 | case JsonTokenType.Comment: 22 | return false; 23 | case JsonTokenType.String: 24 | return reader.GetString() == "1"; 25 | case JsonTokenType.Number: 26 | return reader.GetInt32() == 1; 27 | case JsonTokenType.True: 28 | return true; 29 | case JsonTokenType.False: 30 | return false; 31 | case JsonTokenType.Null: 32 | return false; 33 | default: 34 | break; 35 | } 36 | return reader.GetInt32() == 1; 37 | } 38 | 39 | public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options) 40 | { 41 | writer.WriteNumberValue(value ? 1 : 0); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/ZLMediaKit.WebHook.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5;net6 5 | true 6 | true 7 | ChengXiaoSheng 8 | ZLMediaKit Web Hook 转为C# 委托事件 9 | https://github.com/chengxiaosheng/ZLMediaKit.HttpApi 10 | https://github.com/chengxiaosheng/ZLMediaKit.HttpApi 11 | git 12 | master 13 | ZLMediaKit WebHook HttpApi 14 | zh-Hans 15 | 2.0.2 16 | 2.0.2 17 | 2.0.2 18 | 19 | V2.0.2 : 修复一些数据定义bug 20 | V2.0.1 : WebHook 添加[AllowAnonymous] 21 | V2.0.0 : 适配ZLMediaKit 到 # edbbaa4 22 | V1.0.5 : 适配ZLMediaKit 到 # bad9553 23 | v1.0.4 : 增加mediaserverId;修复部分事件无法获取到对端IP与端口, commit by zlmediaKit : # 6a8268f 24 | v1.0.3 : 增加 FromBody 25 | v1.0.2 : 修复采Autofac全局接管容器时无法注入ZLMediaKitWebHookServcies 的bug 26 | v1.0.1 : 实现ZLMediaKit Http Hook 接口封装 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ZLMediaKit.HttpApi/ZLMediaKit.HttpApi.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5;net6 5 | true 6 | true 7 | 1573 8 | ChengXiaoSheng 9 | 实现ZLMediaKit Api访问 10 | https://github.com/chengxiaosheng/ZLMediaKit.HttpApi 11 | https://github.com/chengxiaosheng/ZLMediaKit.HttpApi 12 | git 13 | master 14 | ZLMediaKit HttpClient HttpApi 15 | zh-Hans 16 | 2.0.2 17 | 2.0.2 18 | 2.0.2 19 | 20 | V2.0.2 : 修复一些数据定义bug 21 | V2.0.1 : WebHook 添加[AllowAnonymous] 22 | V2.0.0 : 适配ZLMediaKit 到 # edbbaa4 23 | V1.0.9 : 适配ZLMediaKit 到 # bad9553 24 | V1.0.8 : 适配多ZLMediaKit交互能力,需要升级ZLMediaKit 到 # 6a8268f 25 | V1.0.7 : 添加媒体时间错等信息 commit by zlmediaKit : # 6a8268f 26 | v1.0.6 : 添加媒体生成源信息 commit: 5cd8e8a 27 | v1.0.5 : addStreamProxy 方法移除 enable_rtsp,enable_rtmp方法 28 | v1.0.4 : 新增 StartSendRtp StopSendRtp 方法 29 | v1.0.3 : 增加MediaInfo->Track-> Fps字段 30 | v1.0.2 : 增加MediaInfo->Track-> codec_type字段 31 | v1.0.1 : 实现ZLMediaKit Http Api 接口封装 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/ZLMediaKitWebHookApplicationModelConvention.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.ApplicationModels; 3 | using Microsoft.AspNetCore.Mvc.Routing; 4 | using ZLMediaKit.WebHook.Services; 5 | 6 | namespace ZLMediaKit.WebHook 7 | { 8 | internal class ZLMediaKitWebHookApplicationModelConvention : IApplicationModelConvention 9 | { 10 | private readonly APIRouteOptions _routeOptions; 11 | 12 | public ZLMediaKitWebHookApplicationModelConvention(APIRouteOptions routeOptions) 13 | { 14 | this._routeOptions = routeOptions; 15 | } 16 | 17 | public void Apply(ApplicationModel application) 18 | { 19 | foreach (var controller in application.Controllers) 20 | { 21 | if (controller.ControllerType == typeof(ZLMediaKitWebHookServcies)) 22 | { 23 | controller.ApiExplorer.GroupName = "ZLMediaKit-WebHook"; 24 | controller.ApiExplorer.IsVisible = true; 25 | foreach (var action in controller.Actions) 26 | { 27 | action.ApiExplorer.IsVisible = true; 28 | var actionName = action.ActionName; 29 | foreach (var item in action.Attributes) 30 | { 31 | if (item is HttpMethodAttribute route) 32 | { 33 | if (!string.IsNullOrEmpty(route.Name)) 34 | { 35 | actionName = route.Name; 36 | } 37 | } 38 | } 39 | action.Selectors[0].AttributeRouteModel = new AttributeRouteModel(new RouteAttribute($"{_routeOptions.RoutePrefix}/{actionName}")); 40 | } 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiGetRtpInfoResult.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 4 | { 5 | public interface IApiGetRtpInfoResult : IApiResultBase 6 | { 7 | /// 8 | /// 是否存在 9 | /// 10 | [JsonPropertyName("exist")] 11 | public bool exist { get; set; } 12 | 13 | /// 14 | /// 本级IP 15 | /// 16 | [JsonPropertyName("local_ip")] 17 | public string LocalIp { get; set; } 18 | /// 19 | /// 本级端口 20 | /// 21 | [JsonPropertyName("local_port")] 22 | public int LocalPort { get; set; } 23 | /// 24 | /// 对端IP 25 | /// 26 | [JsonPropertyName("peer_ip")] 27 | public string PeerIp { get; set; } 28 | /// 29 | /// 对端端口 30 | /// 31 | [JsonPropertyName("peer_port")] 32 | public int PeerPort { get; set; } 33 | } 34 | 35 | public class ApiGetRtpInfoResult : ApiResultBase, IApiGetRtpInfoResult 36 | { 37 | /// 38 | /// 是否存在 39 | /// 40 | [JsonPropertyName("exist")] 41 | public bool exist { get; set; } 42 | 43 | /// 44 | /// 本级IP 45 | /// 46 | [JsonPropertyName("local_ip")] 47 | public string LocalIp { get; set; } 48 | /// 49 | /// 本级端口 50 | /// 51 | [JsonPropertyName("local_port")] 52 | public int LocalPort { get; set; } 53 | /// 54 | /// 对端IP 55 | /// 56 | [JsonPropertyName("peer_ip")] 57 | public string PeerIp { get; set; } 58 | /// 59 | /// 对端端口 60 | /// 61 | [JsonPropertyName("peer_port")] 62 | public int PeerPort { get; set; } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/HookInputDto/IRecordMp4Input.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos.HookInputDto 4 | { 5 | /// 6 | /// 录制mp4完成后通知事件;此事件对回复不敏感 7 | /// 8 | public interface IRecordMp4Input : IHookInputWithMediaBase 9 | { 10 | /// 11 | /// 文件名 12 | /// 13 | [JsonPropertyName("file_name")] 14 | public string FileName { get; } 15 | 16 | /// 17 | /// 文件绝对路径 18 | /// 19 | [JsonPropertyName("file_path")] 20 | public string FilePath { get; } 21 | /// 22 | /// 文件大小,单位字节 23 | /// 24 | [JsonPropertyName("file_size")] 25 | public int FileSize { get; } 26 | 27 | /// 28 | /// 文件所在目录路径 29 | /// 30 | [JsonPropertyName("folder")] 31 | public string Folder { get; } 32 | 33 | /// 34 | /// 开始录制时间戳 35 | /// 36 | [JsonPropertyName("start_time")] 37 | public int StartTime { get; } 38 | /// 39 | /// 录制时长,单位秒 40 | /// 41 | [JsonPropertyName("time_len")] 42 | public int TimeLen { get;} 43 | /// 44 | /// http/rtsp/rtmp点播相对url路径 45 | /// 46 | [JsonPropertyName("url")] 47 | public string Url { get; } 48 | } 49 | /// 50 | /// 录制mp4完成后通知事件;此事件对回复不敏感 51 | /// 52 | public class RecordMp4Input : HookWithMediaBase, IRecordMp4Input 53 | { 54 | public string FileName { get; set; } 55 | 56 | public string FilePath { get; set; } 57 | 58 | public int FileSize { get; set; } 59 | 60 | public string Folder { get; set; } 61 | 62 | public int StartTime { get; set; } 63 | 64 | public int TimeLen { get; set; } 65 | 66 | public string Url { get; set; } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Hosting; 12 | using Microsoft.Extensions.Logging; 13 | 14 | namespace ZLMediaKit.WebHook.Demo 15 | { 16 | public class Startup 17 | { 18 | public Startup(IConfiguration configuration) 19 | { 20 | Configuration = configuration; 21 | } 22 | 23 | public IConfiguration Configuration { get; } 24 | 25 | // This method gets called by the runtime. Use this method to add services to the container. 26 | public void ConfigureServices(IServiceCollection services) 27 | { 28 | services.AddControllers(); 29 | services.AddHostedService(); 30 | services.AddZLMediaKitHttpClient(option => 31 | { 32 | option.IpAddress = "127.0.0.1"; 33 | option.ApiPort = 80; 34 | option.ApiSecret = "035c73f7-bb6b-4889-a715-d9eb2d1925cc"; 35 | }); 36 | services.AddZLMediaKitHttpClient(); 37 | services.AddMediaKitWebHook(new APIRouteOptions(routePrefix: "api/zlhook")); 38 | } 39 | 40 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 42 | { 43 | if (env.IsDevelopment()) 44 | { 45 | app.UseDeveloperExceptionPage(); 46 | } 47 | 48 | app.UseHttpsRedirection(); 49 | 50 | app.UseRouting(); 51 | 52 | app.UseAuthorization(); 53 | 54 | app.UseEndpoints(endpoints => 55 | { 56 | endpoints.MapControllers(); 57 | }); 58 | 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.Logging; 7 | using ZLMediaKit.Common.Dtos.ApiInputDto; 8 | //using ZLMediaKit.HttpApi.Dtos; 9 | 10 | namespace ZLMediaKit.WebHook.Demo.Controllers 11 | { 12 | [ApiController] 13 | [Route("[controller]")] 14 | public class WeatherForecastController : ControllerBase 15 | { 16 | private readonly ZLMediaKit.HttpApi.ZLHttpClient _zLHttpClient; 17 | private static readonly string[] Summaries = new[] 18 | { 19 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 20 | }; 21 | 22 | private readonly ILogger _logger; 23 | 24 | public WeatherForecastController(ILogger logger, HttpApi.ZLHttpClient zLHttpClient) 25 | { 26 | _logger = logger; 27 | this._zLHttpClient = zLHttpClient; 28 | } 29 | 30 | [HttpGet] 31 | public IEnumerable Get() 32 | { 33 | var rng = new Random(); 34 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 35 | { 36 | Date = DateTime.Now.AddDays(index), 37 | TemperatureC = rng.Next(-20, 55), 38 | Summary = Summaries[rng.Next(Summaries.Length)] 39 | }) 40 | .ToArray(); 41 | } 42 | 43 | [HttpGet("GetStatistic")] 44 | public async Task GetStatistic() 45 | { 46 | var value = await _zLHttpClient.GetStatistic(); 47 | return value; 48 | } 49 | 50 | [HttpGet("GetConfig")] 51 | public async Task GetConfig() 52 | { 53 | return await _zLHttpClient.GetServerConfig(); 54 | } 55 | 56 | [HttpGet("GetBin")] 57 | public IActionResult GetdownloadBin() 58 | { 59 | return File(_zLHttpClient.DownloadBin(), "application/octet-stream", "MediaServer.exe"); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ZLMediaKit.HttpApi/Microsoft/Extensions/DependencyInjection/ZLMediaKitHttpApiExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Text.Json; 6 | using ZLMediaKit.Common; 7 | using ZLMediaKit.HttpApi; 8 | 9 | namespace Microsoft.Extensions.DependencyInjection 10 | { 11 | /// 12 | /// 服务注册 13 | /// 14 | public static class ZLMediaKitHttpApiExtension 15 | { 16 | /// 17 | /// 添加ZLMediaKit Http Api Client 18 | /// 19 | /// 20 | /// 21 | /// 22 | public static IServiceCollection AddZLMediaKitHttpClient(this IServiceCollection services, Action options) 23 | { 24 | IZLMediaKitSettings config = new ZLMediaKitSettings(); 25 | options?.Invoke(config); 26 | if (string.IsNullOrEmpty(config.MediaServerId)) throw new InvalidDataException("MediaServerId 不能为空"); 27 | IServerManager.AddServer(config); 28 | return services; 29 | } 30 | /// 31 | /// 添加ZLMediaKit Http Api Client 32 | /// 33 | /// 34 | /// 35 | /// 36 | public static IServiceCollection AddZLMediaKitHttpClient(this IServiceCollection services, Action> options) 37 | { 38 | var configs = new List(); 39 | options.Invoke(configs); 40 | if (configs.Count == 0) throw new InvalidDataException("MediaKit HttpApi 服务配置不能为空"); 41 | foreach (var item in configs) 42 | { 43 | IServerManager.AddServer(item); 44 | } 45 | return services; 46 | 47 | } 48 | 49 | /// 50 | /// 添加ZLMediaKit Http Api Client 51 | /// 不推荐使用此方法 52 | /// 53 | /// 54 | /// 55 | /// 用于与WebHook配合,通过WebHook主动产生ZLMediakitWebClient,需要调用ZLHttpClientRegister.Register 方法进行注册 56 | public static IServiceCollection AddZLMediaKitHttpClient(this IServiceCollection services) 57 | { 58 | return services; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ISocketInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using ZLMediaKit.Common.Dtos.ApiInputDto; 3 | 4 | namespace ZLMediaKit.Common.Dtos 5 | { 6 | /// 7 | /// Socket 连接信息 8 | /// 9 | public interface ISocketInfo : IApiResultDataBase 10 | { 11 | /// 12 | /// tcp 唯一标识 13 | /// 14 | [JsonPropertyName("identifier")] 15 | public string Identifier { get; set; } 16 | /// 17 | /// 本级IP 18 | /// 19 | [JsonPropertyName("local_ip")] 20 | public string LocalIp { get; set; } 21 | /// 22 | /// 本级端口 23 | /// 24 | [JsonPropertyName("local_port")] 25 | public int LocalPort { get; set; } 26 | /// 27 | /// 对端IP 28 | /// 29 | [JsonPropertyName("peer_ip")] 30 | public string PeerIp { get; set; } 31 | /// 32 | /// 对端端口 33 | /// 34 | [JsonPropertyName("peer_port")] 35 | public int PeerPort { get; set; } 36 | 37 | /// 38 | /// 客户端TCPSession typeid 39 | /// 40 | [JsonPropertyName("typeid")] 41 | public string TypeId { get; set; } 42 | } 43 | 44 | /// 45 | /// Socket 连接信息 46 | /// 47 | public class SocketInfo : ISocketInfo 48 | { 49 | /// 50 | /// tcp 唯一标识 51 | /// 52 | [JsonPropertyName("identifier")] 53 | public string Identifier { get; set; } 54 | /// 55 | /// 本级IP 56 | /// 57 | [JsonPropertyName("local_ip")] 58 | public string LocalIp { get; set; } 59 | /// 60 | /// 本级端口 61 | /// 62 | [JsonPropertyName("local_port")] 63 | public int LocalPort { get; set; } 64 | /// 65 | /// 对端IP 66 | /// 67 | [JsonPropertyName("peer_ip")] 68 | public string PeerIp { get; set; } 69 | /// 70 | /// 对端端口 71 | /// 72 | [JsonPropertyName("peer_port")] 73 | public int PeerPort { get; set; } 74 | 75 | /// 76 | /// 客户端TCPSession typeid 77 | /// 78 | [JsonPropertyName("typeid")] 79 | public string TypeId { get; set; } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/ApiInputDto/IApiResultBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text.Json.Serialization; 4 | 5 | namespace ZLMediaKit.Common.Dtos.ApiInputDto 6 | { 7 | public interface IApiResultBase 8 | { 9 | [JsonPropertyName("code")] 10 | public ApiResultCodeType Code { get; set; } 11 | 12 | [JsonPropertyName("msg")] 13 | public string Messag { get; set; } 14 | } 15 | 16 | public interface IApiResultDataBase 17 | { 18 | 19 | } 20 | 21 | public interface IApiResultBase : IApiResultBase //where T : IApiResultDataBase 22 | { 23 | [JsonPropertyName("data")] 24 | public T Data { get; set; } 25 | } 26 | 27 | public interface IApiResultListBase : IApiResultBase where T : IApiResultDataBase 28 | { 29 | [JsonPropertyName("data")] 30 | public IList Data { get; set; } 31 | } 32 | 33 | public interface IApiResultDictBase : IApiResultBase 34 | { 35 | [JsonPropertyName("data")] 36 | public Dictionary Data { get; set; } 37 | } 38 | 39 | public class ApiResultBase: IApiResultBase 40 | { 41 | [JsonPropertyName("code")] 42 | public ApiResultCodeType Code { get; set; } 43 | 44 | [JsonPropertyName("msg")] 45 | public string Messag { get; set; } 46 | } 47 | 48 | public class ApiResultBase : ApiResultBase, IApiResultBase //where T : IApiResultDataBase 49 | { 50 | public T Data { get; set; } 51 | } 52 | 53 | public class ApiResultListBase : ApiResultBase, IApiResultListBase where T : IApiResultDataBase 54 | { 55 | [JsonPropertyName("data")] 56 | public IList Data { get; set; } 57 | } 58 | 59 | public class ApiResultDictBase : ApiResultBase, IApiResultDictBase 60 | { 61 | [JsonPropertyName("data")] 62 | public Dictionary Data { get; set; } 63 | } 64 | 65 | 66 | 67 | 68 | 69 | public enum ApiResultCodeType 70 | { 71 | /// 72 | /// 代码抛异常 73 | /// 74 | Exception = -400, 75 | /// 76 | /// 参数不合法 77 | /// 78 | InvalidArgs = -300,// 79 | /// 80 | /// sql执行失败 81 | /// 82 | SqlFailed = -200,// 83 | /// 84 | /// 鉴权失败 85 | /// 86 | AuthFailed = -100,// 87 | /// 88 | /// 业务代码执行失败 89 | /// 90 | OtherFailed = -1,//, 91 | /// 92 | /// 执行成功 93 | /// 94 | Success = 0// 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/RegisteredModelInstance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using ZLMediaKit.Common.Dtos; 4 | using ZLMediaKit.Common.Dtos.HookResultDto; 5 | using ZLMediaKit.Common; 6 | 7 | namespace ZLMediaKit.WebHook 8 | { 9 | /// 10 | /// 11 | /// 12 | public static class RegisteredModelInstance 13 | { 14 | 15 | 16 | internal static Dictionary ResultModelMapping = new Dictionary() 17 | { 18 | { typeof(IHookReportFlowResult), new HookReportFlowResult() { Code = 0 } }, 19 | { typeof(IHookHttpAccessResult), new HookHttpAccessResult() }, 20 | { typeof(IHookPlayResult), new HookPlayResult() }, 21 | { typeof(IHookPublishResult), new HookPublishResult() }, 22 | { typeof(IHookRecordMp4Result), new HookRecordMp4Result() }, 23 | { typeof(IHookRecordTsResult), new HookRecordTsResult() }, 24 | { typeof(IHookRtspRealmResult), new HookRtspRealmResult() }, 25 | { typeof(IHookRtspAuthResult), new HookRtspAuthResult() }, 26 | { typeof(IHookShellLoginResult), new HookShellLoginResult () { Code = -1, Message = "禁止登录" } }, 27 | { typeof(IHookStreamChangedResult), new HookStreamChangedResult () }, 28 | { typeof(IHookStreamNonReaderResult), new HookStreamNonReaderResult () }, 29 | { typeof(IHookStreamNotFoundResult), new HookStreamNotFoundResult () }, 30 | { typeof(IHookServerStartedResult), new HookServerStartedResult () }, 31 | { typeof(IHookServerKeepaliveResult), new HookServerKeepaliveResult () }, 32 | { typeof(IHookCommonResult), new HookCommonResult() { Code = 0 } }, 33 | }; 34 | 35 | /// 36 | /// 一切为了序列化 37 | /// 38 | /// 39 | /// 40 | public static void RegisterModelMapping() where T : IHookBase where T1 : T, new() 41 | { 42 | TypeMapping.TypeMappings[typeof(T)] = typeof(T1); 43 | } 44 | 45 | /// 46 | /// 替换返回结果 47 | /// 48 | /// 49 | /// 50 | public static void RegisterResultModelMapping(T1 defaultValue) where T : IResultBase where T1 : T, new() 51 | { 52 | ResultModelMapping[typeof(T)] = defaultValue; 53 | } 54 | 55 | internal static T GetResultModelDefault() where T : IResultBase 56 | { 57 | ResultModelMapping.TryGetValue(typeof(T), out var value); 58 | return (T)value; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ZLMediaKit.HttpApi.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.31903.286 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZLMediaKit.HttpApi", "ZLMediaKit.HttpApi\ZLMediaKit.HttpApi.csproj", "{FC1697A7-80D5-40B9-8A03-3CCF62D2D799}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZLMediaKit.WebHook", "ZLMediaKit.WebHook\ZLMediaKit.WebHook.csproj", "{DC722623-BFEB-4FA3-9E7B-1DC3373DDD05}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZLMediaKit.WebHook.Demo", "ZLMediaKit.WebHook.Demo\ZLMediaKit.WebHook.Demo.csproj", "{50BA7D48-3679-46CB-9467-246E2C69AFB6}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZLMediaKit.Common", "ZLMediaKit.Common\ZLMediaKit.Common.csproj", "{AF671696-E9CF-42C8-9A0A-3441E93700F6}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {FC1697A7-80D5-40B9-8A03-3CCF62D2D799}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {FC1697A7-80D5-40B9-8A03-3CCF62D2D799}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {FC1697A7-80D5-40B9-8A03-3CCF62D2D799}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {FC1697A7-80D5-40B9-8A03-3CCF62D2D799}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {DC722623-BFEB-4FA3-9E7B-1DC3373DDD05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {DC722623-BFEB-4FA3-9E7B-1DC3373DDD05}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {DC722623-BFEB-4FA3-9E7B-1DC3373DDD05}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {DC722623-BFEB-4FA3-9E7B-1DC3373DDD05}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {50BA7D48-3679-46CB-9467-246E2C69AFB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {50BA7D48-3679-46CB-9467-246E2C69AFB6}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {50BA7D48-3679-46CB-9467-246E2C69AFB6}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {50BA7D48-3679-46CB-9467-246E2C69AFB6}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {AF671696-E9CF-42C8-9A0A-3441E93700F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {AF671696-E9CF-42C8-9A0A-3441E93700F6}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {AF671696-E9CF-42C8-9A0A-3441E93700F6}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {AF671696-E9CF-42C8-9A0A-3441E93700F6}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {9CE23F74-D4E2-4FE6-9D55-4AC0F91FC5CD} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IKeepalive.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using ZLMediaKit.Common.Dtos.ApiInputDto; 3 | 4 | namespace ZLMediaKit.Common.Dtos 5 | { 6 | public interface IKeepalive : IApiResultDataBase 7 | { 8 | [JsonPropertyName("Buffer")] 9 | public long Buffer { get; set; } 10 | 11 | [JsonPropertyName("BufferRaw")] 12 | public long BufferRaw { get; set; } 13 | 14 | [JsonPropertyName("BufferLikeString")] 15 | public long BufferLikeString { get; set; } 16 | 17 | [JsonPropertyName("BufferList")] 18 | public long BufferList { get; set; } 19 | 20 | [JsonPropertyName("TotalMemUsage")] 21 | public long TotalMemUsage { get; set; } 22 | 23 | [JsonPropertyName("TtotalMemUsageMB")] 24 | public int TtotalMemUsageMB { get; set; } 25 | 26 | [JsonPropertyName("Frame")] 27 | public long Frame { get; set; } 28 | 29 | [JsonPropertyName("FrameImp")] 30 | public long FrameImp { get; set; } 31 | 32 | [JsonPropertyName("MediaSource")] 33 | public long MediaSource { get; set; } 34 | 35 | [JsonPropertyName("MultiMediaSourceMuxer")] 36 | public long MultiMediaSourceMuxer { get; set; } 37 | 38 | [JsonPropertyName("RtmpPacket")] 39 | public long RtmpPacket { get; set; } 40 | [JsonPropertyName("RtpPacket")] 41 | public long RtpPacket { get; set; } 42 | 43 | [JsonPropertyName("Socket")] 44 | public long Socket { get; set; } 45 | 46 | [JsonPropertyName("TcpClient")] 47 | public long TcpClient { get; set; } 48 | [JsonPropertyName("TcpServer")] 49 | public long TcpServer { get; set; } 50 | [JsonPropertyName("TcpSession")] 51 | public long TcpSession { get; set; } 52 | 53 | [JsonPropertyName("UdpSession")] 54 | public long UdpSession { get; set; } 55 | 56 | [JsonPropertyName("UdpServer")] 57 | public long UdpServer { get; set; } 58 | 59 | } 60 | 61 | public class Keepalive : IKeepalive 62 | { 63 | public long Buffer { get; set; } 64 | 65 | public long BufferRaw { get; set; } 66 | 67 | public long BufferLikeString { get; set; } 68 | 69 | public long BufferList { get; set; } 70 | 71 | public long TotalMemUsage { get; set; } 72 | 73 | public int TtotalMemUsageMB { get; set; } 74 | 75 | public long Frame { get; set; } 76 | 77 | public long FrameImp { get; set; } 78 | 79 | public long MediaSource { get; set; } 80 | 81 | public long MultiMediaSourceMuxer { get; set; } 82 | 83 | public long RtmpPacket { get; set; } 84 | public long RtpPacket { get; set; } 85 | 86 | public long Socket { get; set; } 87 | 88 | public long TcpClient { get; set; } 89 | public long TcpServer { get; set; } 90 | public long TcpSession { get; set; } 91 | 92 | public long UdpSession { get; set; } 93 | 94 | public long UdpServer { get; set; } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IHookBase.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos 4 | { 5 | public interface IHookBase 6 | { 7 | /// 8 | /// 服务Id 9 | /// 10 | [JsonPropertyName("mediaServerId")] 11 | public string MediaServerId { get; set; } 12 | 13 | /// 14 | /// 服务地址 15 | /// 16 | public string ZlMediaKitAddress { get; set; } 17 | 18 | public int ZlMediaKitPort { get; set; } 19 | 20 | public IHookBase Clone(); 21 | } 22 | 23 | 24 | public interface IHookInputWithClient : IHookBase 25 | { 26 | /// 27 | /// 客户端IP 28 | /// 29 | [JsonPropertyName("ip")] 30 | public string IP { get; set; } 31 | /// 32 | /// TCP链接唯一ID 33 | /// 34 | [JsonPropertyName("id")] 35 | public string Id { get; set; } 36 | 37 | /// 38 | /// 端口 39 | /// 40 | [JsonPropertyName("port")] 41 | public int Port { get; set; } 42 | /// 43 | /// 推流或播放url参数 44 | /// 45 | [JsonPropertyName("params")] 46 | public string Params { get; set; } 47 | } 48 | 49 | public class HookBase : IHookBase 50 | { 51 | [JsonPropertyName("mediaServerId")] 52 | public string MediaServerId { get; set; } 53 | 54 | public string ZlMediaKitAddress { get; set; } 55 | 56 | public int ZlMediaKitPort { get; set; } 57 | 58 | public IHookBase Clone() 59 | { 60 | return this.MemberwiseClone() as IHookBase; 61 | } 62 | } 63 | 64 | public class HookInputWithClient : HookBase, IHookInputWithClient 65 | { 66 | [JsonPropertyName("ip")] 67 | public string IP { get; set; } 68 | [JsonPropertyName("id")] 69 | public string Id { get; set; } 70 | [JsonPropertyName("port")] 71 | public int Port { get; set; } 72 | [JsonPropertyName("params")] 73 | public virtual string Params { get; set; } 74 | } 75 | 76 | public interface IHookInputWithMediaBaseAndClient : IHookInputWithClient,IMediaBase 77 | { 78 | 79 | } 80 | 81 | /// 82 | /// 83 | /// 84 | public class HookWithMediaBaseAndClient : HookInputWithClient, IHookInputWithMediaBaseAndClient 85 | { 86 | public string Vhost { get; set; } 87 | 88 | public string App { get; set; } 89 | 90 | public string Schema { get; set; } 91 | 92 | public string Stream { get; set; } 93 | } 94 | 95 | public interface IHookInputWithMediaBase : IHookBase, IMediaBase 96 | { 97 | 98 | } 99 | 100 | /// 101 | /// 102 | /// 103 | public class HookWithMediaBase : HookBase , IHookInputWithMediaBase 104 | { 105 | public string Vhost { get; set; } 106 | 107 | public string App { get; set; } 108 | 109 | public string Schema { get; set; } 110 | 111 | public string Stream { get; set; } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IVideoMediaTrack.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace ZLMediaKit.Common.Dtos 4 | { 5 | /// 6 | /// 媒体轨道 7 | /// 8 | public interface IMediaTrack 9 | { 10 | /// 11 | /// H264 = 0, H265 = 1, AAC = 2, G711A = 3, G711U = 4 12 | /// 13 | [JsonPropertyName("codec_id")] 14 | public MediaCodecEnum Codec { get; set; } 15 | /// 16 | /// Video = 0, Audio = 1 17 | /// 18 | [JsonPropertyName("codec_type")] 19 | public MediaCodecTypeEnum CodecType { get; set; } 20 | /// 21 | /// 编码类型名称 22 | /// 23 | [JsonPropertyName("codec_id_name")] 24 | public string CodecName { get; set; } 25 | /// 26 | /// 轨道是否准备就绪 27 | /// 28 | [JsonPropertyName("ready")] 29 | public bool Ready { get; set; } 30 | } 31 | 32 | public interface IVideoMediaTrack : IMediaTrack 33 | { 34 | /// 35 | /// 视频fps 36 | /// 37 | [JsonPropertyName("fps")] 38 | public int Fps { get; set; } 39 | 40 | /// 41 | /// 视频高 42 | /// 43 | [JsonPropertyName("height")] 44 | public int Height { get; set; } 45 | 46 | /// 47 | /// 视 48 | /// 49 | [JsonPropertyName("width")] 50 | public int Width { get; set; } 51 | } 52 | 53 | public interface IAudioMediaTrack : IMediaTrack 54 | { 55 | /// 56 | /// 音频通道数 57 | /// 58 | [JsonPropertyName("channels")] 59 | public int Channels { get; set; } 60 | /// 61 | /// 音频采样位数 62 | /// 63 | [JsonPropertyName("sample_bit")] 64 | public int SampleBit { get; set; } 65 | /// 66 | /// 音频采样 67 | /// 68 | [JsonPropertyName("sample_rate")] 69 | public int SampleRate { get; set; } 70 | } 71 | 72 | public class MediaTrack : IMediaTrack 73 | { 74 | /// 75 | /// H264 = 0, H265 = 1, AAC = 2, G711A = 3, G711U = 4 76 | /// 77 | [JsonPropertyName("codec_id")] 78 | public MediaCodecEnum Codec { get; set; } 79 | /// 80 | /// Video = 0, Audio = 1 81 | /// 82 | [JsonPropertyName("codec_type")] 83 | public MediaCodecTypeEnum CodecType { get; set; } 84 | /// 85 | /// 编码类型名称 86 | /// 87 | [JsonPropertyName("codec_id_name")] 88 | public string CodecName { get; set; } 89 | /// 90 | /// 轨道是否准备就绪 91 | /// 92 | [JsonPropertyName("ready")] 93 | public bool Ready { get; set; } 94 | } 95 | 96 | public class VideoMediaTrack: MediaTrack,IVideoMediaTrack 97 | { 98 | /// 99 | /// 视频fps 100 | /// 101 | [JsonPropertyName("fps")] 102 | public int Fps { get; set; } 103 | 104 | /// 105 | /// 视频高 106 | /// 107 | [JsonPropertyName("height")] 108 | public int Height { get; set; } 109 | 110 | /// 111 | /// 视 112 | /// 113 | [JsonPropertyName("width")] 114 | public int Width { get; set; } 115 | } 116 | 117 | public class AudioMediaTrack: MediaTrack,IAudioMediaTrack 118 | { 119 | /// 120 | /// 音频通道数 121 | /// 122 | [JsonPropertyName("channels")] 123 | public int Channels { get; set; } 124 | /// 125 | /// 音频采样位数 126 | /// 127 | [JsonPropertyName("sample_bit")] 128 | public int SampleBit { get; set; } 129 | /// 130 | /// 音频采样 131 | /// 132 | [JsonPropertyName("sample_rate")] 133 | public int SampleRate { get; set; } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IMediaInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text.Json.Serialization; 3 | using ZLMediaKit.Common.Dtos.ApiInputDto; 4 | 5 | namespace ZLMediaKit.Common.Dtos 6 | { 7 | public interface IMediaInfo: IMediaBase, IApiResultDataBase 8 | { 9 | /// 10 | /// 是否为注册 11 | /// 12 | [JsonPropertyName("regist")] 13 | public bool Regist { get; set; } 14 | /// 15 | /// 存活时间,单位秒 16 | /// 17 | [JsonPropertyName("aliveSecond")] 18 | public int AliveSecond { get; set; } 19 | /// 20 | /// 数据产生速度,单位byte/s 21 | /// 22 | [JsonPropertyName("bytesSpeed")] 23 | public int BytesSpeed { get; set; } 24 | /// 25 | /// GMT unix系统时间戳,单位秒 26 | /// 27 | [JsonPropertyName("createStamp")] 28 | public long CreateStamp { get; set; } 29 | 30 | /// 31 | /// 链接信息 32 | /// 33 | [JsonPropertyName("originSock")] 34 | public ISocketInfo OriginSock { get; set; } 35 | 36 | /// 37 | /// 产生源类型,包括 unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7,rtc_push=8 38 | /// 39 | [JsonPropertyName("originType")] 40 | public OriginTypeEnum OriginType { get; set; } 41 | /// 42 | /// 43 | /// 44 | [JsonPropertyName("originTypeStr")] 45 | public string OriginTypeStr { get; set; } 46 | /// 47 | /// 产生源的url 48 | /// 49 | [JsonPropertyName("originUrl")] 50 | public bool OriginUrl { get; set; } 51 | /// 52 | /// 本协议观看人数 53 | /// 54 | [JsonPropertyName("readerCount")] 55 | public bool ReaderCount { get; set; } 56 | /// 57 | /// 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv/rtc 58 | /// 59 | [JsonPropertyName("totalReaderCount")] 60 | public bool TotalReaderCount { get; set; } 61 | /// 62 | /// 媒体轨道信息 63 | /// 64 | [JsonPropertyName("tracks")] 65 | public List Tracks { get; set; } 66 | 67 | } 68 | 69 | public class MediaInfo: MediaBase, IMediaInfo 70 | { 71 | /// 72 | /// 是否为注册 73 | /// 74 | [JsonPropertyName("regist")] 75 | public bool Regist { get; set; } 76 | /// 77 | /// 存活时间,单位秒 78 | /// 79 | [JsonPropertyName("aliveSecond")] 80 | public int AliveSecond { get; set; } 81 | /// 82 | /// 数据产生速度,单位byte/s 83 | /// 84 | [JsonPropertyName("bytesSpeed")] 85 | public int BytesSpeed { get; set; } 86 | /// 87 | /// GMT unix系统时间戳,单位秒 88 | /// 89 | [JsonPropertyName("createStamp")] 90 | public long CreateStamp { get; set; } 91 | 92 | /// 93 | /// 链接信息 94 | /// 95 | [JsonPropertyName("originSock")] 96 | public ISocketInfo OriginSock { get; set; } 97 | 98 | /// 99 | /// 产生源类型,包括 unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7,rtc_push=8 100 | /// 101 | [JsonPropertyName("originType")] 102 | public OriginTypeEnum OriginType { get; set; } 103 | /// 104 | /// 105 | /// 106 | [JsonPropertyName("originTypeStr")] 107 | public string OriginTypeStr { get; set; } 108 | /// 109 | /// 产生源的url 110 | /// 111 | [JsonPropertyName("originUrl")] 112 | public bool OriginUrl { get; set; } 113 | /// 114 | /// 本协议观看人数 115 | /// 116 | [JsonPropertyName("readerCount")] 117 | public bool ReaderCount { get; set; } 118 | /// 119 | /// 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv/rtc 120 | /// 121 | [JsonPropertyName("totalReaderCount")] 122 | public bool TotalReaderCount { get; set; } 123 | /// 124 | /// 媒体轨道信息 125 | /// 126 | [JsonPropertyName("tracks")] 127 | public List Tracks { get; set; } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZLMediaKit.HttpApi 2 | 基于优秀的开源项目 [ZLMediaKit](http://https://github.com/xia-chu/ZLMediaKit) 提供的[Restful Api](https://github.com/xia-chu/ZLMediaKit/wiki/MediaServer%E6%94%AF%E6%8C%81%E7%9A%84HTTP-API) 实现数据请求 3 | 4 | ## 实现功能 5 | - [x] 封装 ZLMediaKit的Restful Api接口,提供快捷访问 6 | - [x] 支持配置多个MediaKit 7 | - [x] 支持动态添加 MediaKit (比如通过Web Hook动态注册) 8 | 9 | ## 快速开始 10 | 11 | 1. 注入服务 12 | ```C# 13 | services.AddZLMediaKitHttpClient(option => 14 | { 15 | //ZLMediaKit IP地址 16 | option.IpAddress = "127.0.0.1"; 17 | //ZLMediaKit Http 端口 18 | option.ApiPort = 80; 19 | //ZLMediaKit 密钥 20 | option.ApiSecret = "035c73f7-bb6b-4889-a715-d9eb2d1925cc"; 21 | }); 22 | 23 | // ------------------------------------------------------------------------------------- 24 | //通过Web Hook 动态注册 25 | private void ZLMediaKitWebHookEvents_OnServerStarted(Dtos.ServerConfig obj) 26 | { 27 | ZLHttpClientRegister.Register(new ZLMediaKitSettings 28 | { 29 | ApiPort = obj.Http.Port, 30 | ApiSecret = obj.Api.Secret, 31 | HttpSchema = HttpSchema.http, 32 | IpAddress = obj.ServerIp.ToString(), 33 | MediaServerId = obj.General.MediaServerId 34 | }); 35 | } 36 | ``` 37 | 2. 使用 38 | ```C# 39 | public class Test 40 | { 41 | private readonly ZLHttpClient _zlhttpClient; 42 | public Test(ZLHttpClient zlhttpClient) 43 | { 44 | this._zlhttpClient = zlhttpClient 45 | } 46 | //如果您只有一个MediaKit交互,请直接使用此处的方式 47 | public CallTest() 48 | { 49 | _zlhttpClient.GetThreadsLoad(); 50 | _zlhttpClient.GetWorkThreadsLoad(); 51 | _zlhttpClient.GetServerConfig(); 52 | _zlhttpClient.SetServerConfig(); 53 | _zlhttpClient.RestartServer(); 54 | _zlhttpClient.GetMediaList(); 55 | . 56 | . 57 | . 58 | } 59 | 60 | //多个MediaKit 调用方式 61 | //就算您只有一个 MediaKit交互,也可以使用此方法,(但是在服务注册时必须填写 mediaServerId) 62 | public CallTest1() 63 | { 64 | _zlhttpClient.SetMediaServerId("ZLMediaKit配置文件中的,mediaServerId").GetThreadsLoad(); 65 | _zlhttpClient.SetMediaServerId("ZLMediaKit配置文件中的,mediaServerId").GetWorkThreadsLoad(); 66 | _zlhttpClient.SetMediaServerId("ZLMediaKit配置文件中的,mediaServerId").GetServerConfig(); 67 | _zlhttpClient.SetMediaServerId("ZLMediaKit配置文件中的,mediaServerId").SetServerConfig(); 68 | _zlhttpClient.SetMediaServerId("ZLMediaKit配置文件中的,mediaServerId").RestartServer(); 69 | _zlhttpClient.SetMediaServerId("ZLMediaKit配置文件中的,mediaServerId").GetMediaList(); 70 | . 71 | . 72 | . 73 | } 74 | 75 | } 76 | ``` 77 | 78 | --- 79 | 80 | # ZLMediaKit.WebHook 81 | 基于优秀的开源项目 [ZLMediaKit](http://https://github.com/xia-chu/ZLMediaKit) 提供的 [Web Hook](https://github.com/xia-chu/ZLMediaKit/wiki/MediaServer%E6%94%AF%E6%8C%81%E7%9A%84HTTP-HOOK-API)实现接收请求 82 | 83 | ## 实现功能 84 | - [x] 接入 ZLMediaKit WebHook 85 | - [x] 自定义路由路径 86 | - [x] 以事件的形式访问 87 | 88 | ## 快速开始 89 | 1. 注入服务 90 | ```C# 91 | //routePrefix 参数设定路由前缀 92 | //实际接口路径为 routePrefix/action 93 | //ps : index/hook/on_flow_report 94 | //routePrefix = app/index/api/test 95 | //ps : app/index/api/test/on_flow_report 96 | services.AddMediaKitWebHook(new APIRouteOptions(routePrefix : "index/hook"); 97 | ``` 98 | 2. 绑定事件 99 | ``` 100 | ZLMediaKitWebHookEvents.OnFlowReport += ZLMediaKitWebHookEvents_OnFlowReport; 101 | ZLMediaKitWebHookEvents.OnHttpAccess += ZLMediaKitWebHookEvents_OnHttpAccess; 102 | ZLMediaKitWebHookEvents.OnPlay += ZLMediaKitWebHookEvents_OnPlay; 103 | ZLMediaKitWebHookEvents.OnPublish += ZLMediaKitWebHookEvents_OnPublish; 104 | ZLMediaKitWebHookEvents.OnRecordMP4 += ZLMediaKitWebHookEvents_OnRecordMP4; 105 | ZLMediaKitWebHookEvents.OnRtspAuth += ZLMediaKitWebHookEvents_OnRtspAuth; 106 | ZLMediaKitWebHookEvents.OnRtspRealm += ZLMediaKitWebHookEvents_OnRtspRealm; 107 | ZLMediaKitWebHookEvents.OnServerStarted += ZLMediaKitWebHookEvents_OnServerStarted; 108 | ZLMediaKitWebHookEvents.OnShellLogin += ZLMediaKitWebHookEvents_OnShellLogin; 109 | ZLMediaKitWebHookEvents.OnStreamChanged += ZLMediaKitWebHookEvents_OnStreamChanged; 110 | ZLMediaKitWebHookEvents.OnStreamNoneReader += LMediaKitWebHookEvents_OnStreamNoneReader; 111 | ZLMediaKitWebHookEvents.OnStreamNotFound += LMediaKitWebHookEvents_OnStreamNotFound; 112 | ``` 113 | 114 | 115 | # 致敬 116 | 117 | 一个优秀而强大的流媒体服务器 [ZLMediaKit](https://github.com/xia-chu/ZLMediaKit) 118 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook.Demo/HookService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Hosting; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | //using ZLMediaKit.HttpApi; 9 | 10 | namespace ZLMediaKit.WebHook.Demo 11 | { 12 | public class HookService : IHostedService 13 | { 14 | //private readonly ZLHttpClient _zLHttpClient; 15 | //public HookService(ZLHttpClient zLHttpClient) 16 | //{ 17 | // _zLHttpClient = zLHttpClient; 18 | //} 19 | 20 | CancellationTokenSource CancellationToken = default; 21 | public Task StartAsync(CancellationToken cancellationToken) 22 | { 23 | ZLMediaKitWebHookEvents.OnPublish += ZLMediaKitWebHookEvents_OnPublish; 24 | ZLMediaKitWebHookEvents.OnServerStarted += ZLMediaKitWebHookEvents_OnServerStarted; 25 | ZLMediaKitWebHookEvents.OnStreamChanged += ZLMediaKitWebHookEvents_OnStreamChanged; 26 | ZLMediaKitWebHookEvents.OnShellLogin += ZLMediaKitWebHookEvents_OnShellLogin; 27 | ZLMediaKitWebHookEvents.OnServerKeepalive += ZLMediaKitWebHookEvents_OnServerKeepalive; 28 | ZLMediaKitWebHookEvents.OnHttpAccess += ZLMediaKitWebHookEvents_OnHttpAccess; 29 | return Task.Run(() => 30 | { 31 | CancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); 32 | 33 | }, cancellationToken); 34 | } 35 | 36 | private Task ZLMediaKitWebHookEvents_OnHttpAccess(Common.Dtos.EventArgs.IHookEventArgs hookEventArgs) 37 | { 38 | Console.WriteLine($"收到http 访问 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEventArgs.Payload)}"); 39 | return Task.FromResult(new Common.Dtos.HookResultDto.HookHttpAccessResult 40 | { 41 | Code = 0, 42 | Message = "googd job", 43 | Path = String.Empty, 44 | Second = 1800 45 | } as Common.Dtos.HookResultDto.IHookHttpAccessResult); 46 | } 47 | 48 | private async Task ZLMediaKitWebHookEvents_OnServerKeepalive(Common.Dtos.EventArgs.IHookEventArgs hookEvent) 49 | { 50 | Console.WriteLine($"收到心跳数据 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEvent.Payload)}"); 51 | Console.WriteLine($"收到心跳数据 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEvent.ServerManager?? default)}"); 52 | return; 53 | } 54 | 55 | private Task ZLMediaKitWebHookEvents_OnShellLogin(Common.Dtos.EventArgs.IHookEventArgs hookEventArgs) 56 | { 57 | Console.WriteLine($"收到登录数据 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEventArgs)}"); 58 | return Task.FromResult( new Common.Dtos.HookResultDto.HookCommonResult() 59 | { 60 | Code = 0, 61 | Message = "允许登录" 62 | } as Common.Dtos.HookResultDto.IHookShellLoginResult); 63 | } 64 | 65 | private Task ZLMediaKitWebHookEvents_OnStreamChanged(Common.Dtos.EventArgs.IHookEventArgs hookEventArgs) 66 | { 67 | Console.WriteLine($"收到心跳数据 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEventArgs)}"); 68 | throw new NotImplementedException(); 69 | } 70 | 71 | private async Task ZLMediaKitWebHookEvents_OnServerStarted(Common.Dtos.EventArgs.IHookEventArgs hookEventArgs) 72 | { 73 | Console.WriteLine($"服务器启动 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEventArgs.Payload)}"); 74 | Console.WriteLine($"服务器启动 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEventArgs.ServerManager)}"); 75 | return ; 76 | } 77 | 78 | private Task ZLMediaKitWebHookEvents_OnPublish(Common.Dtos.EventArgs.IHookEventArgs hookEventArgs) 79 | { 80 | Console.WriteLine($"收到心跳数据 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEventArgs)}"); 81 | throw new NotImplementedException(); 82 | } 83 | 84 | public Task StopAsync(CancellationToken cancellationToken) 85 | { 86 | //Console.WriteLine($"收到心跳数据 {Environment.NewLine} {System.Text.Json.JsonSerializer.Serialize(hookEventArgs)}"); 87 | return Task.CompletedTask; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /ZLMediaKit.HttpApi.Test/WebHookEventTest.cs: -------------------------------------------------------------------------------- 1 | using Flurl.Http.Configuration; 2 | using NUnit.Framework; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using ZLMediaKit.WebHook; 7 | using ZLMediaKit.WebHook.Dtos; 8 | using Flurl.Http; 9 | using Flurl; 10 | using Newtonsoft.Json.Linq; 11 | using System.Threading; 12 | using System.Net; 13 | using Microsoft.Extensions.Hosting; 14 | 15 | namespace ZLMediaKit.HttpApi.Test 16 | { 17 | [TestFixture] 18 | public class WebHookEventTest 19 | { 20 | private const string BaseUrl = "https://localhost:5001/index/hook"; 21 | public WebHookEventTest() 22 | { 23 | 24 | } 25 | 26 | [SetUp] 27 | public void Init() 28 | { 29 | ZLMediaKitWebHookEvents.OnFlowReport += ZLMediaKitWebHookEvents_OnFlowReport; 30 | ZLMediaKitWebHookEvents.OnHttpAccess += ZLMediaKitWebHookEvents_OnHttpAccess; 31 | ZLMediaKitWebHookEvents.OnPlay += ZLMediaKitWebHookEvents_OnPlay; 32 | ZLMediaKitWebHookEvents.OnPublish += ZLMediaKitWebHookEvents_OnPublish; 33 | ZLMediaKitWebHookEvents.OnRecordMP4 += ZLMediaKitWebHookEvents_OnRecordMP4; 34 | ZLMediaKitWebHookEvents.OnRtspAuth += ZLMediaKitWebHookEvents_OnRtspAuth; 35 | ZLMediaKitWebHookEvents.OnRtspRealm += ZLMediaKitWebHookEvents_OnRtspRealm; 36 | ZLMediaKitWebHookEvents.OnServerStarted += ZLMediaKitWebHookEvents_OnServerStarted; 37 | ZLMediaKitWebHookEvents.OnShellLogin += ZLMediaKitWebHookEvents_OnShellLogin; 38 | ZLMediaKitWebHookEvents.OnStreamChanged += ZLMediaKitWebHookEvents_OnStreamChanged; 39 | ZLMediaKitWebHookEvents.OnStreamNoneReader += ZLMediaKitWebHookEvents_OnStreamNoneReader; 40 | ZLMediaKitWebHookEvents.OnStreamNotFound += ZLMediaKitWebHookEvents_OnStreamNotFound; 41 | 42 | } 43 | 44 | [Test] 45 | public void OnFlowReport_Test() 46 | { 47 | var dict = new Dictionary 48 | { 49 | { "app" , "live" }, 50 | { "duration" , 6 }, 51 | { "params" , "token=1677193e-1244-49f2-8868-13b3fcc31b17" }, 52 | { "player" , false }, 53 | { "schema" , "rtmp" }, 54 | { "stream" , "obs" }, 55 | { "totalBytes" , 1508161 }, 56 | { "vhost" , "__defaultVhost__" }, 57 | { "ip" , "192.168.0.21" }, 58 | { "port" , 55345 }, 59 | { "id" , "140259799100960" } 60 | }; 61 | var http = BaseUrl.AppendPathSegment("on_flow_report") 62 | .PostJsonAsync(dict).ContinueWith(task => 63 | { 64 | Assert.IsFalse(task.IsFaulted || task.Exception != null, message: "流量上报失败"); 65 | Assert.AreEqual(task.Result.StatusCode, HttpStatusCode.OK, message: "状态码不对"); 66 | }); 67 | http.Wait(); 68 | 69 | 70 | } 71 | 72 | 73 | private void ZLMediaKitWebHookEvents_OnStreamNotFound(StreamNotFoundInfo obj) 74 | { 75 | Console.WriteLine("收到事件"); 76 | } 77 | 78 | private StreamNoneReaderInfoResult ZLMediaKitWebHookEvents_OnStreamNoneReader(StreamNoneReaderInfo arg) 79 | { 80 | throw new NotImplementedException(); 81 | } 82 | 83 | private void ZLMediaKitWebHookEvents_OnStreamChanged(StreamChangedInfo obj) 84 | { 85 | throw new NotImplementedException(); 86 | } 87 | 88 | private ShellLonginResult ZLMediaKitWebHookEvents_OnShellLogin(ShellLoginInfo arg) 89 | { 90 | throw new NotImplementedException(); 91 | } 92 | 93 | private void ZLMediaKitWebHookEvents_OnServerStarted(ServerConfig obj) 94 | { 95 | throw new NotImplementedException(); 96 | } 97 | 98 | private RtspRealmInfoResult ZLMediaKitWebHookEvents_OnRtspRealm(RtspRealmInfo arg) 99 | { 100 | throw new NotImplementedException(); 101 | } 102 | 103 | private RtspAuthResult ZLMediaKitWebHookEvents_OnRtspAuth(RtspAuthInfo arg) 104 | { 105 | throw new NotImplementedException(); 106 | } 107 | 108 | private void ZLMediaKitWebHookEvents_OnRecordMP4(RecordInfo obj) 109 | { 110 | throw new NotImplementedException(); 111 | } 112 | 113 | private PublishResult ZLMediaKitWebHookEvents_OnPublish(PublishInfo arg) 114 | { 115 | throw new NotImplementedException(); 116 | } 117 | 118 | private PlayInfoResult ZLMediaKitWebHookEvents_OnPlay(PlayInfo arg) 119 | { 120 | throw new NotImplementedException(); 121 | } 122 | 123 | private HttpAccessResult ZLMediaKitWebHookEvents_OnHttpAccess(HttpAccess arg) 124 | { 125 | throw new NotImplementedException(); 126 | } 127 | 128 | private void ZLMediaKitWebHookEvents_OnFlowReport(FlowReport obj) 129 | { 130 | throw new NotImplementedException(); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/ServerManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using ZLMediaKit.Common.Dtos; 5 | 6 | namespace ZLMediaKit.Common 7 | { 8 | public interface IServerManager : IZLMediaKitSettings 9 | { 10 | //internal IServerManager GetBySettings(IZLMediaKitSettings settings); 11 | 12 | public DateTime? StartTime { get; set; } 13 | /// 14 | /// 最后一次心跳时间 15 | /// 16 | public DateTime? KeepaliveTime { get; set; } 17 | 18 | /// 19 | /// 服务器配置 20 | /// 21 | public IServerConfig ServerConfig { get; set; } 22 | 23 | 24 | 25 | /// 26 | /// 服务器心跳信息 27 | /// 28 | public IKeepalive Keepalive { get; set; } 29 | 30 | #region static 31 | 32 | public static Dictionary Instances { get; set; } = new Dictionary(); 33 | 34 | public static IServerManager GetServerManager(IHookBase hookBase) => GetServerManager(hookBase?.MediaServerId); 35 | 36 | public static IServerManager GetServerManager(string mediaServerId = null) 37 | { 38 | if (string.IsNullOrEmpty(mediaServerId)) return null; 39 | Instances.TryGetValue(mediaServerId, out var serverManager); 40 | return serverManager; 41 | } 42 | 43 | public static IServerManager GetDefaultServerManager() 44 | { 45 | return Instances.FirstOrDefault(w => !string.IsNullOrEmpty(w.Value.ApiBaseUri)).Value; 46 | } 47 | 48 | /// 49 | /// 新增一个服务 50 | /// 51 | /// 52 | /// 53 | /// 54 | public static void AddServer(IServerManager server) 55 | { 56 | if (server == null) throw new ArgumentNullException(nameof(server)); 57 | //if (Instances.ContainsKey(server.MediaServerId)) throw new ArgumentException("此平台已存在"); 58 | Instances[server.MediaServerId] = server; 59 | } 60 | 61 | public static void AddServer(IZLMediaKitSettings settings) 62 | { 63 | if (settings == null) throw new ArgumentNullException(nameof(settings)); 64 | Instances[settings.MediaServerId] = new ServerManager().GetBySettings(settings); 65 | } 66 | 67 | /// 68 | /// 删除一个服务器 69 | /// 70 | /// 71 | /// 72 | /// 73 | public static bool RemoveServer(IServerManager server) 74 | { 75 | if (server == null) throw new ArgumentNullException(nameof(server)); 76 | return RemoveServer(server.MediaServerId); 77 | } 78 | 79 | /// 80 | /// 删除一个服务器 81 | /// 82 | /// 83 | /// 84 | /// 85 | public static bool RemoveServer(string mediaServerId) 86 | { 87 | if (string.IsNullOrEmpty(mediaServerId)) throw new ArgumentNullException(nameof(mediaServerId)); 88 | return IServerManager.Instances.Remove(mediaServerId); 89 | } 90 | 91 | 92 | 93 | /// 94 | /// 停止一个服务 95 | /// 96 | /// 97 | /// 98 | /// 99 | /// 100 | public static bool Stop(string mediaServerId) => GetServerManager(mediaServerId)?.Stop() ?? false; 101 | 102 | 103 | /// 104 | /// 停止一个服务 105 | /// 106 | /// 107 | /// 108 | /// 109 | public static bool Stop(IServerManager server) => server?.Stop() ?? false; 110 | 111 | #endregion static 112 | 113 | /// 114 | /// 停止一个服务 115 | /// 116 | /// 117 | /// 118 | /// 119 | public bool Stop(); 120 | 121 | 122 | } 123 | /// 124 | /// 服务器管理 125 | /// 126 | public sealed class ServerManager : ZLMediaKitSettings, IServerManager 127 | { 128 | 129 | public IServerConfig ServerConfig { get; set; } 130 | 131 | public IKeepalive Keepalive { get; set; } 132 | 133 | public DateTime? StartTime { get; set; } 134 | 135 | public DateTime? KeepaliveTime { get; set; } 136 | 137 | public string ServerAddress { get; set; } 138 | 139 | public bool Stop() 140 | { 141 | return true; 142 | } 143 | 144 | internal IServerManager GetBySettings(IZLMediaKitSettings settings) 145 | { 146 | this.MediaServerId = settings.MediaServerId; 147 | this.IpAddress = settings.IpAddress; 148 | this.HttpSchema = settings.HttpSchema; 149 | this.ApiPort = settings.ApiPort; 150 | this.Timeout = settings.Timeout; 151 | return this; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | *.db 215 | 216 | # Business Intelligence projects 217 | *.rdl.data 218 | *.bim.layout 219 | *.bim_*.settings 220 | 221 | # Microsoft Fakes 222 | FakesAssemblies/ 223 | 224 | # GhostDoc plugin setting file 225 | *.GhostDoc.xml 226 | 227 | # Node.js Tools for Visual Studio 228 | .ntvs_analysis.dat 229 | 230 | # Visual Studio 6 build log 231 | *.plg 232 | 233 | # Visual Studio 6 workspace options file 234 | *.opt 235 | 236 | # Visual Studio LightSwitch build output 237 | **/*.HTMLClient/GeneratedArtifacts 238 | **/*.DesktopClient/GeneratedArtifacts 239 | **/*.DesktopClient/ModelManifest.xml 240 | **/*.Server/GeneratedArtifacts 241 | **/*.Server/ModelManifest.xml 242 | _Pvt_Extensions 243 | 244 | # Paket dependency manager 245 | .paket/paket.exe 246 | paket-files/ 247 | 248 | # FAKE - F# Make 249 | .fake/ 250 | 251 | # JetBrains Rider 252 | .idea/ 253 | *.sln.iml 254 | 255 | # MediaServer 256 | src/MediaServer.Web/Logs/* 257 | src/MediaServer.Web.Host/Logs/* 258 | src/MediaServer.IdentityServer/Logs/* 259 | src/MediaServer.HttpApi.Host/Logs/* 260 | src/MediaServer.HttpApi.Host/Logs/* 261 | src/MediaServer.DbMigrator/Logs/* 262 | 263 | src/MediaServer.*.xml 264 | 265 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/TypeMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text.Encodings.Web; 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | using ZLMediaKit.Common.Dtos; 7 | using ZLMediaKit.Common.Dtos.ApiInputDto; 8 | using ZLMediaKit.Common.Dtos.HookInputDto; 9 | 10 | namespace ZLMediaKit.Common 11 | { 12 | /// 13 | /// 全局统一的类型映射 14 | /// 15 | public static class TypeMapping 16 | { 17 | static TypeMapping() 18 | { 19 | // HookInput 20 | SerializerOptions.Converters.Add(new ZLBoolConverter()); 21 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 22 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 23 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 24 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 25 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 26 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 27 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 28 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 29 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 30 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 31 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 32 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 33 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 34 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 35 | 36 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 37 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 38 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 39 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 40 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 41 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 42 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 43 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 44 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 45 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 46 | // ServerConfig 47 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 48 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 49 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 50 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 51 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 52 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 53 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 54 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 55 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 56 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 57 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 58 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 59 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 60 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 61 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 62 | 63 | // Api 64 | 65 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 66 | //SerializerOptions.Converters.Add(new TypeMappingConvert>, ApiResultDictBase>>()); 67 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 68 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 69 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 70 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 71 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 72 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 73 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 74 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 75 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 76 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 77 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 78 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 79 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 80 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 81 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 82 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 83 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 84 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 85 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 86 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 87 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 88 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 89 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 90 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 91 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 92 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 93 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 94 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 95 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 96 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 97 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 98 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 99 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 100 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 101 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 102 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 103 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 104 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 105 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 106 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 107 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 108 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 109 | SerializerOptions.Converters.Add(new TypeMappingConvert()); 110 | 111 | } 112 | /// 113 | /// 类型映射,用于序列化数据时采用其他类型进行,以便处理一些特殊化的内容 114 | /// 115 | /// 接口类型 116 | /// 对接口的实现类型 117 | /// 118 | public static Dictionary TypeMappings = new Dictionary(); 119 | /// 120 | /// 全局统一的json 序列化配置 121 | /// 122 | /// 123 | public static JsonSerializerOptions SerializerOptions = new JsonSerializerOptions 124 | { 125 | WriteIndented = true, 126 | PropertyNameCaseInsensitive = true, 127 | NumberHandling = JsonNumberHandling.AllowReadingFromString, 128 | Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping 129 | 130 | }; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/ZLMediaKitWebHookEvents.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using ZLMediaKit.Common.Dtos.EventArgs; 3 | using ZLMediaKit.Common.Dtos.HookInputDto; 4 | using ZLMediaKit.Common.Dtos.HookResultDto; 5 | 6 | namespace ZLMediaKit.WebHook 7 | { 8 | /// 9 | /// 10 | /// 11 | public class ZLMediaKitWebHookEvents 12 | { 13 | 14 | /// 15 | /// 流量统计事件,播放器或推流器断开时并且耗用流量超过特定阈值时会触发此事件,阈值通过配置文件 16 | /// 17 | /// 18 | public delegate Task FlowReportEventHandle(IHookEventArgs hookEventArgs); 19 | /// 20 | /// 流量统计事件,播放器或推流器断开时并且耗用流量超过特定阈值时会触发此事件,阈值通过配置文件 21 | /// 22 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 23 | public static event FlowReportEventHandle OnFlowReport; 24 | internal static async Task OnFlowReport_Call(IHookEventArgs hookEventArgs) 25 | { 26 | _ = OnFlowReport?.Invoke(hookEventArgs).ConfigureAwait(false); 27 | return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 28 | } 29 | 30 | /// 31 | /// 访问http文件服务器上hls之外的文件时触发 32 | /// 33 | /// 34 | /// 35 | public delegate Task HttpAccessEventHandle(IHookEventArgs hookEventArgs); 36 | 37 | /// 38 | /// 访问http文件服务器上hls之外的文件时触发。 39 | /// 40 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 41 | public static event HttpAccessEventHandle OnHttpAccess; 42 | 43 | internal static bool OnHttpAccess_IsNull => OnHttpAccess == null; 44 | internal static async Task OnHttpAccess_Call(IHookEventArgs hookEventArgs) 45 | { 46 | if (OnHttpAccess == null) return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 47 | return await OnHttpAccess(hookEventArgs); 48 | } 49 | 50 | /// 51 | /// 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件 52 | /// 53 | /// 如果流不存在,那么先触发on_play事件然后触发on_stream_not_found事件; 54 | /// 播放rtsp流时,如果该流启动了rtsp专属鉴权(on_rtsp_realm)那么将不再触发on_play事件。 55 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 56 | /// 57 | public delegate Task PlayEventHandle(IHookEventArgs hookEventArgs); 58 | /// 59 | /// 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件 60 | /// 61 | /// 如果流不存在,那么先触发on_play事件然后触发on_stream_not_found事件; 62 | /// 播放rtsp流时,如果该流启动了rtsp专属鉴权(on_rtsp_realm)那么将不再触发on_play事件。 63 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 64 | /// 65 | public static event PlayEventHandle OnPlay; 66 | internal static async Task OnPlay_Call(IHookEventArgs hookEventArgs) 67 | { 68 | if (OnPlay == null) return RegisteredModelInstance.GetResultModelDefault(); 69 | return await OnPlay(hookEventArgs); 70 | } 71 | /// 72 | /// rtsp/rtmp/rtp推流鉴权事件 73 | /// 74 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 75 | public delegate Task PublishEventHandle(IHookEventArgs hookEventArgs); 76 | /// 77 | /// rtsp/rtmp/rtp推流鉴权事件 78 | /// 79 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 80 | public static event PublishEventHandle OnPublish; 81 | internal static async Task OnPublish_Call(IHookEventArgs hookEventArgs) 82 | { 83 | if (OnPublish == null) return RegisteredModelInstance.GetResultModelDefault(); 84 | return await OnPublish(hookEventArgs); 85 | } 86 | 87 | 88 | /// 89 | /// 录制mp4完成后通知事件 90 | /// 91 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 92 | public delegate Task RecordMp4EventHandle(IHookEventArgs hookEventArgs); 93 | 94 | /// 95 | /// 录制mp4完成后通知事件 96 | /// 97 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 98 | public static event RecordMp4EventHandle OnRecordMP4; 99 | internal static async Task OnRecordMP4_Call(IHookEventArgs hookEventArgs) 100 | { 101 | _ = OnRecordMP4?.Invoke(hookEventArgs).ConfigureAwait(false); 102 | return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 103 | } 104 | /// 105 | /// 录制TS完成后通知事件 106 | /// 107 | /// 108 | /// 109 | public delegate Task RecordTsEventHandle(IHookEventArgs hookEventArgs); 110 | 111 | /// 112 | /// 录制TS完成后通知事件 113 | /// 114 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 115 | public static event RecordTsEventHandle OnRecordTS; 116 | internal static async Task OnRecordTS_Call(IHookEventArgs hookEventArgs) 117 | { 118 | _ = OnRecordTS?.Invoke(hookEventArgs).ConfigureAwait(false); 119 | return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 120 | } 121 | 122 | 123 | /// 124 | /// 该rtsp流是否开启rtsp专用方式的鉴权事件,开启后才会触发on_rtsp_auth事件。 125 | /// 需要指出的是rtsp也支持url参数鉴权,它支持两种方式鉴权。 126 | /// 127 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 128 | public delegate Task RtspRealmEventHandle(IHookEventArgs hookEventArgs); 129 | /// 130 | /// 该rtsp流是否开启rtsp专用方式的鉴权事件,开启后才会触发on_rtsp_auth事件。 131 | /// 需要指出的是rtsp也支持url参数鉴权,它支持两种方式鉴权。 132 | /// 133 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 134 | public static event RtspRealmEventHandle OnRtspRealm; 135 | internal static async Task OnRtspRealm_Call(IHookEventArgs hookEventArgs) 136 | { 137 | if (OnRtspRealm == null) return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 138 | return await OnRtspRealm(hookEventArgs); 139 | } 140 | 141 | /// 142 | /// rtsp专用的鉴权事件,先触发on_rtsp_realm事件然后才会触发on_rtsp_auth事件。 143 | /// 144 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 145 | public delegate Task RtspAuthEventHandle(IHookEventArgs hookEventArgs); 146 | 147 | 148 | /// 149 | /// rtsp专用的鉴权事件,先触发on_rtsp_realm事件然后才会触发on_rtsp_auth事件。 150 | /// 151 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 152 | public static event RtspAuthEventHandle OnRtspAuth; 153 | internal static async Task OnRtspAuth_Call(IHookEventArgs hookEventArgs) 154 | { 155 | if (OnRtspAuth == null) return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 156 | return await OnRtspAuth(hookEventArgs); 157 | } 158 | 159 | /// 160 | /// shell登录鉴权,ZLMediaKit提供简单的telnet调试方式 161 | /// 使用telnet 127.0.0.1 9000能进入MediaServer进程的shell界面 162 | /// 163 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 164 | public delegate Task ShellLoginEventHandle(IHookEventArgs hookEventArgs); 165 | 166 | /// 167 | /// shell登录鉴权,ZLMediaKit提供简单的telnet调试方式 168 | /// 使用telnet 127.0.0.1 9000能进入MediaServer进程的shell界面 169 | /// 170 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 171 | public static event ShellLoginEventHandle OnShellLogin; 172 | internal static async Task OnShellLogin_Call(IHookEventArgs hookEventArgs) 173 | { 174 | if (OnShellLogin == null) return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 175 | return await OnShellLogin(hookEventArgs); 176 | } 177 | 178 | /// 179 | /// rtsp/rtmp流注册或注销时触发此事件 180 | /// 181 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 182 | public delegate Task StreamChangedEventHandle(IHookEventArgs hookEventArgs); 183 | /// 184 | /// rtsp/rtmp流注册或注销时触发此事件 185 | /// 186 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 187 | public static event StreamChangedEventHandle OnStreamChanged; 188 | internal static async Task OnStreamChanged_Call(IHookEventArgs hookEventArgs) 189 | { 190 | _ = OnStreamChanged?.Invoke(hookEventArgs).ConfigureAwait(false); 191 | return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 192 | } 193 | 194 | /// 195 | /// 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 196 | /// 197 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 198 | public delegate Task StreamNonReaderEventHandle(IHookEventArgs hookEventArgs); 199 | 200 | /// 201 | /// 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 202 | /// 203 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 204 | public static event StreamNonReaderEventHandle OnStreamNoneReader; 205 | internal static async Task OnStreamNoneReader_Call(IHookEventArgs hookEventArgs) 206 | { 207 | if (OnStreamNoneReader == null) return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 208 | return await OnStreamNoneReader(hookEventArgs); 209 | } 210 | 211 | /// 212 | /// 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流 213 | /// 214 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 215 | public delegate Task StreamNotFoundEventHandle(IHookEventArgs hookEventArgs); 216 | 217 | /// 218 | /// 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流 219 | /// 220 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 221 | public static event StreamNotFoundEventHandle OnStreamNotFound; 222 | internal static async Task OnStreamNotFound_Call(IHookEventArgs hookEventArgs) 223 | { 224 | _ = OnStreamNotFound?.Invoke(hookEventArgs); 225 | return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 226 | } 227 | 228 | /// 229 | /// 服务器启动事件,可以用于监听服务器崩溃重启 230 | /// 231 | /// 232 | /// 233 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 234 | public delegate Task SeverStartedEventHandle(IHookEventArgs hookEventArgs); 235 | 236 | /// 237 | /// 服务器启动事件,可以用于监听服务器崩溃重启 238 | /// 239 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 240 | public static event SeverStartedEventHandle OnServerStarted; 241 | internal static async Task OnServerStarted_Call(IHookEventArgs hookEventArgs) 242 | { 243 | _ = OnServerStarted?.Invoke(hookEventArgs).ConfigureAwait(false); 244 | return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 245 | } 246 | 247 | /// 248 | /// 服务器定时上报时间,上报间隔可配置,默认10s上报一次 249 | /// 250 | /// 251 | /// 252 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 253 | public delegate Task ServerKeepaliveEventHandle(IHookEventArgs hookEvent); 254 | /// 255 | /// 服务器定时上报时间,上报间隔可配置,默认10s上报一次 256 | /// 257 | /// 详情请查看 https://github.com/xia-chu/ZLMediaKit/wiki 258 | public static event ServerKeepaliveEventHandle OnServerKeepalive; 259 | internal static async Task OnServerKeepalive_Call(IHookEventArgs hookEventArgs) 260 | { 261 | _ = OnServerKeepalive?.Invoke(hookEventArgs); 262 | return await Task.FromResult(RegisteredModelInstance.GetResultModelDefault()); 263 | } 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /ZLMediaKit.WebHook/Services/ZLMediaKitWebHookServcies.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.AspNetCore.Mvc; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Dynamic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Text.Json.Serialization; 11 | using System.Threading.Tasks; 12 | using ZLMediaKit.Common; 13 | using ZLMediaKit.Common.Dtos; 14 | using ZLMediaKit.Common.Dtos.EventArgs; 15 | using ZLMediaKit.Common.Dtos.HookInputDto; 16 | using ZLMediaKit.Common.Dtos.HookResultDto; 17 | 18 | namespace ZLMediaKit.WebHook.Services 19 | { 20 | //[EnableCors] 21 | /// 22 | /// Web Hook Service 23 | /// 24 | [AllowAnonymous] 25 | public class ZLMediaKitWebHookServcies 26 | { 27 | private readonly IHttpContextAccessor _contextAccessor; 28 | /// 29 | /// 构造 30 | /// 31 | /// 32 | public ZLMediaKitWebHookServcies(IHttpContextAccessor contextAccessor) 33 | { 34 | this._contextAccessor = contextAccessor; 35 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 36 | } 37 | 38 | private void SetServerInfo(IHookBase eventBase) 39 | { 40 | eventBase.ZlMediaKitAddress = _contextAccessor?.HttpContext?.Connection?.RemoteIpAddress.ToString(); 41 | eventBase.ZlMediaKitPort = _contextAccessor?.HttpContext?.Connection?.RemotePort ?? 0; 42 | 43 | 44 | } 45 | 46 | private async Task Execute(T value, Func> func) where T : IHookBase 47 | { 48 | _contextAccessor.HttpContext.Request.Body.Position = 0; 49 | TypeMapping.TypeMappings.TryGetValue(typeof(T), out var type); 50 | //RegisteredModelInstance.ModelMappding.TryGetValue(typeof(T), out var type); 51 | 52 | // 如果有类型映射,则获取类型映射的值, 否则保持原样 53 | if (type != null) 54 | { 55 | value = (T)System.Text.Json.JsonSerializer.Deserialize(_contextAccessor.HttpContext.Request.Body, type, TypeMapping.SerializerOptions); 56 | } 57 | else value = System.Text.Json.JsonSerializer.Deserialize(_contextAccessor.HttpContext.Request.Body, TypeMapping.SerializerOptions); 58 | value.ZlMediaKitPort = _contextAccessor?.HttpContext?.Connection?.RemotePort ?? 0; 59 | value.ZlMediaKitAddress = _contextAccessor?.HttpContext?.Connection?.RemoteIpAddress.ToString(); 60 | return await func(value); 61 | } 62 | 63 | private async Task Execute(T value, Func> func) where T : IHookBase where T1 : IResultBase 64 | { 65 | //RegisteredModelInstance.ModelMappding.TryGetValue(typeof(T), out var type); 66 | TypeMapping.TypeMappings.TryGetValue(typeof(T), out var type); 67 | _contextAccessor.HttpContext.Request.EnableBuffering(); 68 | _contextAccessor.HttpContext.Request.Body.Position = 0; 69 | var requestReader = new StreamReader(_contextAccessor.HttpContext.Request.Body); 70 | var requestContent = await requestReader.ReadToEndAsync(); 71 | 72 | if (type != null) 73 | { 74 | value = (T)System.Text.Json.JsonSerializer.Deserialize(requestContent, type, TypeMapping.SerializerOptions); 75 | } 76 | else value = System.Text.Json.JsonSerializer.Deserialize(requestContent, TypeMapping.SerializerOptions); 77 | 78 | // 如果有类型映射,则获取类型映射的值, 否则保持原样 79 | 80 | 81 | value.ZlMediaKitPort = _contextAccessor?.HttpContext?.Connection?.RemotePort ?? 0; 82 | value.ZlMediaKitAddress = _contextAccessor?.HttpContext?.Connection?.RemoteIpAddress.ToString(); 83 | var result = await func(value); 84 | if (result != null) return Json(result); 85 | return Json(new HookCommonResult()); 86 | 87 | } 88 | 89 | /// 90 | /// 流量统计事件,播放器或推流器断开时并且耗用流量超过特定阈值时会触发此事件,阈值通过配置文件 91 | /// 92 | /// 93 | [HttpPost(Name = "on_flow_report")] 94 | [ProducesResponseType(typeof(IHookReportFlowResult),200)] 95 | public async Task FlowReportAsync() => 96 | await Execute(default(IReportFlowInput), model => ZLMediaKitWebHookEvents.OnFlowReport_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 97 | 98 | 99 | /// 100 | /// 访问http文件服务器上hls之外的文件时触发 101 | /// 102 | /// 103 | [HttpPost(Name = "on_http_access")] 104 | [ProducesResponseType(typeof(IHookHttpAccessResult),200)] 105 | public async Task HttpAccessAsync() 106 | { 107 | 108 | return await Execute(default(IHttpAccessInput), model => 109 | { 110 | var headers = System.Text.Json.JsonSerializer.Deserialize>(_contextAccessor.HttpContext.Request.Body).Where(w => w.Key.StartsWith("header.", StringComparison.OrdinalIgnoreCase)).Select(s => new { Key = s.Key.Replace("header.", String.Empty, StringComparison.OrdinalIgnoreCase), Value = s.Value }).ToDictionary(k => k.Key, v => v.Value); 111 | model.InitHeader(headers); 112 | return ZLMediaKitWebHookEvents.OnHttpAccess_Call(new HookEventArgs(_contextAccessor.HttpContext, model)); 113 | }); 114 | } 115 | 116 | /// 117 | /// 播放器鉴权事件,rtsp/rtmp/http-flv/ws-flv/hls的播放都将触发此鉴权事件 118 | /// 119 | /// 如果流不存在,那么先触发on_play事件然后触发on_stream_not_found事件; 120 | /// 播放rtsp流时,如果该流启动了rtsp专属鉴权(on_rtsp_realm)那么将不再触发on_play事件。 121 | /// 122 | [HttpPost(Name = "on_play")] 123 | [ProducesResponseType(typeof(IHookPlayResult),200)] 124 | public async Task PlayAsync() => 125 | await Execute(default(IPlayInput), model => ZLMediaKitWebHookEvents.OnPlay_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 126 | 127 | /// 128 | /// rtsp/rtmp/rtp推流鉴权事件 129 | /// 130 | /// 131 | [HttpPost(Name = "on_publish")] 132 | [ProducesResponseType(typeof(IHookPublishResult),200)] 133 | public async Task PublishAsync() 134 | => await Execute(default(IPublishInput), model => ZLMediaKitWebHookEvents.OnPublish_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 135 | 136 | /// 137 | /// 录制mp4完成后通知事件;此事件对回复不敏感 138 | /// 139 | /// 140 | [HttpPost(Name = "on_record_mp4")] 141 | [ProducesResponseType(typeof(IHookRecordMp4Result),200)] 142 | public async Task RecordMp4Async() 143 | => await Execute(default(IRecordMp4Input), model => ZLMediaKitWebHookEvents.OnRecordMP4_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 144 | 145 | /// 146 | /// 录制TS完成后通知事件;此事件对回复不敏感 147 | /// 148 | /// 149 | [HttpPost(Name = "on_record_ts")] 150 | [ProducesResponseType(typeof(IHookRecordTsResult),200)] 151 | public async Task RecordTsAsync() 152 | => await Execute(default(IRecordTsInput), model => ZLMediaKitWebHookEvents.OnRecordTS_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 153 | 154 | /// 155 | /// 该rtsp流是否开启rtsp专用方式的鉴权事件,开启后才会触发on_rtsp_auth事件 156 | /// 157 | /// 需要指出的是rtsp也支持url参数鉴权,它支持两种方式鉴权 158 | [HttpPost(Name = "on_rtsp_realm")] 159 | [ProducesResponseType(typeof(IHookRtspRealmResult),200)] 160 | public async Task RtspRealmAsync() 161 | => await Execute(default(IRtspRealmInput), model => ZLMediaKitWebHookEvents.OnRtspRealm_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 162 | 163 | 164 | /// 165 | /// rtsp专用的鉴权事件,先触发on_rtsp_realm事件然后才会触发on_rtsp_auth事件。 166 | /// 167 | /// 168 | [HttpPost(Name = "on_rtsp_auth")] 169 | [ProducesResponseType(typeof(IHookRtspAuthResult),200)] 170 | public async Task RtspAuthAsync() 171 | => await Execute(default(IRtspAuthInput), model => ZLMediaKitWebHookEvents.OnRtspAuth_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 172 | 173 | 174 | /// 175 | /// shell登录鉴权,ZLMediaKit提供简单的telnet调试方式; 176 | /// 使用telnet 127.0.0.1 9000能进入MediaServer进程的shell界面 177 | /// 178 | /// 179 | [HttpPost(Name = "on_shell_login")] 180 | [ProducesResponseType(typeof(IHookShellLoginResult),200)] 181 | public async Task ShellLoginAsync() 182 | => await Execute(default(IShellLoginInput), model => ZLMediaKitWebHookEvents.OnShellLogin_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 183 | 184 | 185 | /// 186 | /// rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 187 | /// 188 | /// 189 | [HttpPost(Name = "on_stream_changed")] 190 | [ProducesResponseType(typeof(IHookStreamChangedResult),200)] 191 | public async Task StreamChangedAsync() 192 | => await Execute(default(IStreamChangedInput), model => ZLMediaKitWebHookEvents.OnStreamChanged_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 193 | 194 | 195 | /// 196 | /// 流无人观看时事件,用户可以通过此事件选择是否关闭无人看的流。 197 | /// 198 | /// 199 | [HttpPost(Name = "on_stream_none_reader")] 200 | [ProducesResponseType(typeof(IHookStreamNonReaderResult),200)] 201 | public async Task StreamNoneReaderAsync() 202 | => await Execute(default(IStreamNoneReaderInput), model => ZLMediaKitWebHookEvents.OnStreamNoneReader_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 203 | 204 | 205 | /// 206 | /// 流未找到事件,用户可以在此事件触发时,立即去拉流,这样可以实现按需拉流;此事件对回复不敏感 207 | /// 208 | /// 209 | [HttpPost(Name = "on_stream_not_found")] 210 | [ProducesResponseType(typeof(IHookStreamNotFoundResult),200)] 211 | public async Task StreamNotFoundAsync() 212 | => await Execute(default(IStreamNotFoundInuut), model => ZLMediaKitWebHookEvents.OnStreamNotFound_Call(new HookEventArgs(_contextAccessor.HttpContext, model))); 213 | 214 | /// 215 | /// 服务器启动事件,可以用于监听服务器崩溃重启;此事件对回复不敏感。 216 | /// 217 | /// 218 | /// 219 | [HttpPost(Name = "on_server_started")] 220 | [ProducesResponseType(typeof(IHookServerStartedResult),200)] 221 | public async Task ServerStartedAsync([FromBody] Dictionary dicts) 222 | { 223 | 224 | var groups = dicts.Select(s => new { Key = s.Key.Split('.'), Value = s.Value }) 225 | .Select(s => new { ClassName = s.Key.Length == 2 ? s.Key[0].Replace("_", String.Empty) : "rootElement", Key = s.Key.LastOrDefault(), Value = s.Value }) 226 | .GroupBy(x => x.ClassName); 227 | IDictionary result = new ExpandoObject(); 228 | foreach (var group in groups) 229 | { 230 | IDictionary temp = new ExpandoObject(); 231 | foreach (var item in group) 232 | { 233 | if (group.Key == "rootElement") 234 | { 235 | result[item.Key] = item.Value; 236 | } 237 | else 238 | temp.Add(item.Key, item.Value); 239 | } 240 | result.Add(group.Key, temp); 241 | } 242 | var jsonStr = System.Text.Json.JsonSerializer.Serialize(result as ExpandoObject); 243 | var serverCofnig = System.Text.Json.JsonSerializer.Deserialize(jsonStr, TypeMapping.SerializerOptions); 244 | var serviceManager = IServerManager.GetServerManager(serverCofnig); 245 | if (serviceManager == null) 246 | { 247 | serviceManager = new ServerManager() 248 | { 249 | MediaServerId = serverCofnig.MediaServerId, 250 | }; 251 | IServerManager.Instances[serverCofnig.MediaServerId] = serviceManager; 252 | } 253 | serviceManager.StartTime = DateTime.Now; 254 | serviceManager.ServerConfig = serverCofnig; 255 | 256 | serverCofnig.ZlMediaKitPort = _contextAccessor?.HttpContext?.Connection?.RemotePort ?? 0; 257 | serverCofnig.ZlMediaKitAddress = _contextAccessor?.HttpContext?.Connection?.RemoteIpAddress.ToString(); 258 | 259 | return await ZLMediaKitWebHookEvents.OnServerStarted_Call(new HookEventArgs(_contextAccessor.HttpContext, serverCofnig)).ContinueWith(t => Json(t.Result)); 260 | } 261 | 262 | /// 263 | /// 心跳 264 | /// 265 | /// 266 | [HttpPost(Name = "on_server_keepalive")] 267 | [ProducesResponseType(typeof(IHookServerKeepaliveResult),200)] 268 | public async Task ServerKeepalive() 269 | { 270 | return await Execute(default(IServerKeepaliveInput), model => 271 | { 272 | var serverManager = IServerManager.GetServerManager(model); 273 | if (serverManager != null) 274 | { 275 | serverManager.Keepalive = model; 276 | serverManager.KeepaliveTime = DateTime.Now; 277 | } 278 | return ZLMediaKitWebHookEvents.OnServerKeepalive_Call(new HookEventArgs(_contextAccessor.HttpContext, model)); 279 | }); 280 | } 281 | 282 | 283 | private IActionResult Json(object data) 284 | { 285 | return new ContentResult() 286 | { 287 | Content = System.Text.Json.JsonSerializer.Serialize(data, TypeMapping.SerializerOptions), 288 | ContentType = "application/json;charset=utf-8", 289 | }; 290 | } 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /ZLMediaKit.Common/Dtos/IServerConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | using ZLMediaKit.Common.Dtos.ApiInputDto; 3 | 4 | namespace ZLMediaKit.Common.Dtos 5 | { 6 | public interface IServerConfig : IApiResultDataBase 7 | { 8 | public IApiConfig Api { get; set; } 9 | public IFFmpegConfig FFmpeg { get; set; } 10 | public IGeneralConfig General { get; set; } 11 | public IHlsConfig Hls { get; set; } 12 | public IHookConfig Hook { get; set; } 13 | public IHttpConfig Http { get; set; } 14 | public IMulticastConfig Multicast { get; set; } 15 | public IRecordConfig Record { get; set; } 16 | public IRtmpConfig Rtmp { get; set; } 17 | public IRtpConfig Rtp { get; set; } 18 | public IRtpProxyConfig RtpProxy { get; set; } 19 | public IRtcConfig Rtc { get; set; } 20 | public IRtspConfig Rtsp { get; set; } 21 | public IShellConfig Shell { get; set; } 22 | } 23 | 24 | public class ServerConfig : IServerConfig 25 | { 26 | public IApiConfig Api { get; set; } 27 | public IFFmpegConfig FFmpeg { get; set; } 28 | public IGeneralConfig General { get; set; } 29 | public IHlsConfig Hls { get; set; } 30 | public IHookConfig Hook { get; set; } 31 | public IHttpConfig Http { get; set; } 32 | public IMulticastConfig Multicast { get; set; } 33 | public IRecordConfig Record { get; set; } 34 | public IRtmpConfig Rtmp { get; set; } 35 | public IRtpConfig Rtp { get; set; } 36 | public IRtpProxyConfig RtpProxy { get; set; } 37 | public IRtcConfig Rtc { get; set; } 38 | public IRtspConfig Rtsp { get; set; } 39 | public IShellConfig Shell { get; set; } 40 | } 41 | 42 | 43 | #region api config 44 | 45 | public interface IApiConfig 46 | { 47 | /// 48 | /// 是否调试http api,启用调试后,会打印每次http请求的内容和回复 49 | /// 50 | [JsonPropertyName("apiDebug")] 51 | [JsonConverter(typeof(ZLBoolConverter))] 52 | public bool ApiDebug { get; set; } 53 | /// 54 | /// 一些比较敏感的http api在访问时需要提供secret,否则无权限调用 55 | /// 如果是通过127.0.0.1访问,那么可以不提供secret 56 | /// 57 | [JsonPropertyName("secret")] 58 | public string Secret { get; set; } 59 | /// 60 | /// 截图保存路径根目录,截图通过http api(/index/api/getSnap)生成和获取 61 | /// 62 | [JsonPropertyName("snapRoot")] 63 | public string SnapRoot { get; set; } 64 | /// 65 | /// 默认截图图片,在启动FFmpeg截图后但是截图还未生成时,可以返回默认的预设图片 66 | /// 67 | [JsonPropertyName("defaultSnap")] 68 | public string DefaultSnap { get; set; } 69 | } 70 | 71 | public class ApiConfig : IApiConfig 72 | { 73 | [JsonConverter(typeof(ZLBoolConverter))] 74 | public bool ApiDebug { get; set; } = true; 75 | public string Secret { get; set; } = "035c73f7-bb6b-4889-a715-d9eb2d1925cc"; 76 | public string SnapRoot { get; set; } = "./www/snap/"; 77 | public string DefaultSnap { get; set; } = "./www/logo.png"; 78 | } 79 | 80 | #endregion api config 81 | 82 | #region ffmpeg config 83 | public interface IFFmpegConfig 84 | { 85 | /// 86 | /// FFmpeg可执行程序绝对路径 87 | /// 88 | [JsonPropertyName("bin")] 89 | public string Bin { get; set; } 90 | /// 91 | /// FFmpeg拉流再推流的命令模板,通过该模板可以设置再编码的一些参数 92 | /// 93 | [JsonPropertyName("cmd")] 94 | public string Cmd { get; set; } 95 | /// 96 | /// FFmpeg生成截图的命令,可以通过修改该配置改变截图分辨率或质量 97 | /// 98 | [JsonPropertyName("snap")] 99 | public string Snap { get; set; } 100 | /// 101 | /// FFmpeg日志的路径,如果置空则不生成FFmpeg日志 102 | /// 可以为相对(相对于本可执行程序目录)或绝对路径 103 | /// 104 | [JsonPropertyName("log")] 105 | public string Log { get; set; } 106 | } 107 | 108 | public class FFmpegConfig : IFFmpegConfig 109 | { 110 | public virtual string Bin { get; set; } = "/usr/bin/ffmpeg"; 111 | public virtual string Cmd { get; set; } = "% s - re - i % s - c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s"; 112 | public virtual string Snap { get; set; } = "% s - i % s - y - f mjpeg -t 0.001 %s"; 113 | public virtual string Log { get; set; } = "./ ffmpeg / ffmpeg.log"; 114 | } 115 | #endregion ffmpeg config 116 | 117 | #region general config 118 | 119 | public interface IGeneralConfig 120 | { 121 | /// 122 | /// 是否启用虚拟主机 123 | /// 124 | [JsonPropertyName("enableVhost")] 125 | [JsonConverter(typeof(ZLBoolConverter))] 126 | public bool EnableVhost { get; set; } 127 | /// 128 | /// 播放器或推流器在断开后会触发hook.on_flow_report事件(使用多少流量事件), 129 | /// flowThreshold参数控制触发hook.on_flow_report事件阈值,使用流量超过该阈值后才触发,单位KB 130 | /// 131 | [JsonPropertyName("flowThreshold")] 132 | public int FlowThreshold { get; set; } 133 | /// 134 | ///播放最多等待时间,单位毫秒 135 | ///播放在播放某个流时,如果该流不存在, 136 | ///ZLMediaKit会最多让播放器等待maxStreamWaitMS毫秒 137 | ///如果在这个时间内,该流注册成功,那么会立即返回播放器播放成功 138 | ///否则返回播放器未找到该流,该机制的目的是可以先播放再推流 139 | /// 140 | [JsonPropertyName("maxStreamWaitMS")] 141 | public int MaxStreamWaitMS { get; set; } 142 | /// 143 | ///某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒 144 | ///在配合hook.on_stream_none_reader事件时,可以做到无人观看自动停止拉流或停止接收推流 145 | /// 146 | [JsonPropertyName("streamNoneReaderDelayMS")] 147 | public int StreamNoneReaderDelayMS { get; set; } 148 | /// 149 | ///拉流代理是否添加静音音频(直接拉流模式本协议无效) 150 | /// 151 | [JsonPropertyName("addMuteAudio")] 152 | [JsonConverter(typeof(ZLBoolConverter))] 153 | public bool AddMuteAudio { get; set; } 154 | /// 155 | ///拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始, 156 | ///如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写) 157 | /// 158 | [JsonPropertyName("resetWhenRePlay")] 159 | [JsonConverter(typeof(ZLBoolConverter))] 160 | public bool ResetWhenRePlay { get; set; } 161 | /// 162 | ///是否默认推流时转换成hls,hook接口(on_publish)中可以覆盖该设置 163 | /// 164 | [JsonPropertyName("publishToHls")] 165 | [JsonConverter(typeof(ZLBoolConverter))] 166 | public bool PublishToHls { get; set; } 167 | /// 168 | ///是否默认推流时mp4录像,hook接口(on_publish)中可以覆盖该设置 169 | /// 170 | [JsonPropertyName("publishToMP4")] 171 | [JsonConverter(typeof(ZLBoolConverter))] 172 | public bool PublishToMP4 { get; set; } 173 | /// 174 | ///合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时 175 | ///开启后会同时关闭TCP_NODELAY并开启MSG_MORE 176 | /// 177 | [JsonPropertyName("mergeWriteMS")] 178 | [JsonConverter(typeof(ZLBoolConverter))] 179 | public bool MergeWriteMS { get; set; } 180 | /// 181 | ///全局的时间戳覆盖开关,在转协议时,对frame进行时间戳覆盖 182 | ///该开关对rtsp/rtmp/rtp推流、rtsp/rtmp/hls拉流代理转协议时生效 183 | ///会直接影响rtsp/rtmp/hls/mp4/flv等协议的时间戳 184 | ///同协议情况下不影响(例如rtsp/rtmp推流,那么播放rtsp/rtmp时不会影响时间戳) 185 | /// 186 | [JsonPropertyName("modifyStamp")] 187 | [JsonConverter(typeof(ZLBoolConverter))] 188 | public bool ModifyStamp { get; set; } 189 | /// 190 | ///服务器唯一id,用于触发hook时区别是哪台服务器 191 | /// 192 | [JsonPropertyName("mediaServerId")] 193 | public string MediaServerId { get; set; } 194 | /// 195 | ///转协议是否全局开启或关闭音频 196 | /// 197 | [JsonPropertyName("enable_audio")] 198 | [JsonConverter(typeof(ZLBoolConverter))] 199 | public bool EnableAudio { get; set; } 200 | 201 | /// 202 | ///hls协议是否按需生成,如果hls.segNum配置为0(意味着hls录制),那么hls将一直生成(不管此开关) 203 | /// 204 | [JsonPropertyName("hls_demand")] 205 | [JsonConverter(typeof(ZLBoolConverter))] 206 | public bool HlsDemand { get; set; } 207 | /// 208 | ///rtsp[s]协议是否按需生成 209 | /// 210 | [JsonPropertyName("rtsp_demand")] 211 | [JsonConverter(typeof(ZLBoolConverter))] 212 | public bool RtspDemand { get; set; } 213 | /// 214 | ///rtmp[s]、http[s]-flv、ws[s]-flv协议是否按需生成 215 | /// 216 | [JsonPropertyName("rtmp_demand")] 217 | [JsonConverter(typeof(ZLBoolConverter))] 218 | public bool RtmpDemand { get; set; } 219 | /// 220 | ///http[s]-ts协议是否按需生成 221 | /// 222 | [JsonPropertyName("ts_demand")] 223 | [JsonConverter(typeof(ZLBoolConverter))] 224 | public bool TsDemand { get; set; } 225 | /// 226 | ///http[s]-fmp4、ws[s]-fmp4协议是否按需生成 227 | /// 228 | [JsonPropertyName("fmp4_demand")] 229 | [JsonConverter(typeof(ZLBoolConverter))] 230 | public bool Fmp4Demand { get; set; } 231 | } 232 | 233 | public class GeneralConfig : IGeneralConfig 234 | { 235 | public virtual bool EnableVhost { get; set; } = false; 236 | public virtual int FlowThreshold { get; set; } = 1024; 237 | public virtual int MaxStreamWaitMS { get; set; } = 15000; 238 | public virtual int StreamNoneReaderDelayMS { get; set; } = 20000; 239 | [JsonConverter(typeof(ZLBoolConverter))] 240 | public virtual bool AddMuteAudio { get; set; } = true; 241 | [JsonConverter(typeof(ZLBoolConverter))] 242 | public virtual bool ResetWhenRePlay { get; set; } = true; 243 | [JsonConverter(typeof(ZLBoolConverter))] 244 | public virtual bool PublishToHls { get; set; } = true; 245 | [JsonConverter(typeof(ZLBoolConverter))] 246 | public virtual bool PublishToMP4 { get; set; } = false; 247 | [JsonConverter(typeof(ZLBoolConverter))] 248 | public virtual bool MergeWriteMS { get; set; } = false; 249 | [JsonConverter(typeof(ZLBoolConverter))] 250 | public virtual bool ModifyStamp { get; set; } = false; 251 | public virtual string MediaServerId { get; set; } = "your_server_id"; 252 | [JsonConverter(typeof(ZLBoolConverter))] 253 | public virtual bool EnableAudio { get; set; } = true; 254 | [JsonConverter(typeof(ZLBoolConverter))] 255 | public virtual bool HlsDemand { get; set; } = false; 256 | [JsonConverter(typeof(ZLBoolConverter))] 257 | public virtual bool RtspDemand { get; set; } = false; 258 | [JsonConverter(typeof(ZLBoolConverter))] 259 | public virtual bool RtmpDemand { get; set; } = false; 260 | [JsonConverter(typeof(ZLBoolConverter))] 261 | public virtual bool TsDemand { get; set; } = false; 262 | [JsonConverter(typeof(ZLBoolConverter))] 263 | public virtual bool Fmp4Demand { get; set; } = false; 264 | } 265 | 266 | #endregion 267 | 268 | #region 269 | public interface IHlsConfig 270 | { 271 | /// 272 | /// hls写文件的buf大小,调整参数可以提高文件io性能 273 | /// 274 | [JsonPropertyName("fileBufSize")] 275 | public int FileBufSize { get; set; } 276 | /// 277 | /// hls保存文件路径 278 | /// 可以为相对(相对于本可执行程序目录)或绝对路径 279 | /// 280 | [JsonPropertyName("filePath")] 281 | public string FilePath { get; set; } 282 | /// 283 | /// hls最大切片时间 284 | /// 285 | [JsonPropertyName("segDur")] 286 | public int SegDur { get; set; } 287 | /// 288 | /// m3u8索引中,hls保留切片个数(实际保留切片个数大2~3个) 289 | /// 如果设置为0,则不删除切片,而是保存为点播 290 | /// 291 | [JsonPropertyName("segNum")] 292 | public int SegNum { get; set; } 293 | /// 294 | /// HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数 295 | /// 296 | [JsonPropertyName("segRetain")] 297 | public int SegRetain { get; set; } 298 | /// 299 | /// 是否广播 ts 切片完成通知 300 | /// 301 | [JsonPropertyName("broadcastRecordTs")] 302 | [JsonConverter(typeof(ZLBoolConverter))] 303 | public bool BroadcastRecordTs { get; set; } 304 | /// 305 | /// 直播hls文件删除延时,单位秒,issue: //913 306 | /// 307 | [JsonPropertyName("deleteDelaySec")] 308 | public int DeleteDelaySec { get; set; } 309 | } 310 | 311 | public class HlsConfig : IHlsConfig 312 | { 313 | /// 314 | /// hls写文件的buf大小,调整参数可以提高文件io性能 315 | /// 316 | [JsonPropertyName("fileBufSize")] 317 | public virtual int FileBufSize { get; set; } = 65536; 318 | /// 319 | /// hls保存文件路径 320 | /// 可以为相对(相对于本可执行程序目录)或绝对路径 321 | /// 322 | [JsonPropertyName("filePath")] 323 | public virtual string FilePath { get; set; } = "./www"; 324 | /// 325 | /// hls最大切片时间 326 | /// 327 | [JsonPropertyName("segDur")] 328 | public virtual int SegDur { get; set; } = 2; 329 | /// 330 | /// m3u8索引中,hls保留切片个数(实际保留切片个数大2~3个) 331 | /// 如果设置为0,则不删除切片,而是保存为点播 332 | /// 333 | [JsonPropertyName("segNum")] 334 | public virtual int SegNum { get; set; } = 3; 335 | /// 336 | /// HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数 337 | /// 338 | [JsonPropertyName("segRetain")] 339 | public virtual int SegRetain { get; set; } = 5; 340 | /// 341 | /// 是否广播 ts 切片完成通知 342 | /// 343 | [JsonPropertyName("broadcastRecordTs")] 344 | [JsonConverter(typeof(ZLBoolConverter))] 345 | public virtual bool BroadcastRecordTs { get; set; } = false; 346 | /// 347 | /// 直播hls文件删除延时,单位秒,issue: //913 348 | /// 349 | [JsonPropertyName("deleteDelaySec")] 350 | public virtual int DeleteDelaySec { get; set; } = 0; 351 | } 352 | #endregion 353 | 354 | #region hook cofnig 355 | 356 | public interface IHookConfig 357 | { 358 | /// 359 | /// 在推流时,如果url参数匹对admin_params,那么可以不经过hook鉴权直接推流成功,播放时亦然 360 | /// 该配置项的目的是为了开发者自己调试测试,该参数暴露后会有泄露隐私的安全隐患 361 | /// 362 | [JsonPropertyName("admin_params")] 363 | public string AdminParams { get; set; } 364 | /// 365 | /// 是否启用hook事件,启用后,推拉流都将进行鉴权 366 | /// 367 | [JsonPropertyName("enable")] 368 | [JsonConverter(typeof(ZLBoolConverter))] 369 | public bool Enable { get; set; } 370 | /// 371 | /// 播放器或推流器使用流量事件,置空则关闭 372 | /// 373 | [JsonPropertyName("on_flow_report")] 374 | public string OnFlowReport { get; set; } 375 | /// 376 | /// 访问http文件鉴权事件,置空则关闭鉴权 377 | /// 378 | [JsonPropertyName("on_http_access")] 379 | public string OnHttpAccess { get; set; } 380 | /// 381 | /// 播放鉴权事件,置空则关闭鉴权 382 | /// 383 | [JsonPropertyName("on_play")] 384 | public string OnPlay { get; set; } 385 | /// 386 | /// 推流鉴权事件,置空则关闭鉴权 387 | /// 388 | [JsonPropertyName("on_publish")] 389 | public string OnPublish { get; set; } 390 | /// 391 | /// 录制mp4切片完成事件 392 | /// 393 | [JsonPropertyName("on_record_mp4")] 394 | public string OnRecordMp4 { get; set; } 395 | /// 396 | /// 录制 hls ts 切片完成事件 397 | /// 398 | [JsonPropertyName("on_record_ts")] 399 | public string NnRecordTs { get; set; } 400 | /// 401 | /// rtsp播放鉴权事件,此事件中比对rtsp的用户名密码 402 | /// 403 | [JsonPropertyName("on_rtsp_auth")] 404 | public string NnRtspAuth { get; set; } 405 | /// 406 | /// rtsp播放是否开启专属鉴权事件,置空则关闭rtsp鉴权。rtsp播放鉴权还支持url方式鉴权 407 | /// 建议开发者统一采用url参数方式鉴权,rtsp用户名密码鉴权一般在设备上用的比较多 408 | /// 开启rtsp专属鉴权后,将不再触发on_play鉴权事件 409 | /// 410 | [JsonPropertyName("on_rtsp_realm")] 411 | public string OnRtspRealm { get; set; } 412 | /// 413 | /// 远程telnet调试鉴权事件 414 | /// 415 | [JsonPropertyName("on_shell_login")] 416 | public string OnShellLogin { get; set; } 417 | /// 418 | /// 直播流注册或注销事件 419 | /// 420 | [JsonPropertyName("on_stream_changed")] 421 | public string OnStreamChanged { get; set; } 422 | /// 423 | /// 无人观看流事件,通过该事件,可以选择是否关闭无人观看的流。配合general.streamNoneReaderDelayMS选项一起使用 424 | /// 425 | [JsonPropertyName("on_stream_none_reader")] 426 | public string OnStreamNoneReader { get; set; } 427 | /// 428 | /// 播放时,未找到流事件,通过配合hook.on_stream_none_reader事件可以完成按需拉流 429 | /// 430 | [JsonPropertyName("on_stream_not_found")] 431 | public string OnStreamNotFound { get; set; } 432 | /// 433 | /// 服务器启动报告,可以用于服务器的崩溃重启事件监听 434 | /// 435 | [JsonPropertyName("on_server_started")] 436 | public string OnServerStarted { get; set; } 437 | /// 438 | /// server保活上报 439 | /// 440 | [JsonPropertyName("on_server_keepalive")] 441 | public string OnServerKeepalive { get; set; } 442 | /// 443 | /// hook api最大等待回复时间,单位秒 444 | /// 445 | public int TimeoutSec { get; set; } 446 | /// 447 | /// keepalive hook触发间隔,单位秒,float类型 448 | /// 449 | [JsonPropertyName("alive_interval")] 450 | public float AliveInterval { get; set; } 451 | } 452 | 453 | public class HookConfig : IHookConfig 454 | { 455 | /// 456 | /// 在推流时,如果url参数匹对admin_params,那么可以不经过hook鉴权直接推流成功,播放时亦然 457 | /// 该配置项的目的是为了开发者自己调试测试,该参数暴露后会有泄露隐私的安全隐患 458 | /// 459 | [JsonPropertyName("admin_params")] 460 | public virtual string AdminParams { get; set; } = "035c73f7-bb6b-4889-a715-d9eb2d1925cc"; 461 | /// 462 | /// 是否启用hook事件,启用后,推拉流都将进行鉴权 463 | /// 464 | [JsonPropertyName("enable")] 465 | [JsonConverter(typeof(ZLBoolConverter))] 466 | public virtual bool Enable { get; set; } = false; 467 | /// 468 | /// 播放器或推流器使用流量事件,置空则关闭 469 | /// 470 | [JsonPropertyName("on_flow_report")] 471 | public virtual string OnFlowReport { get; set; } = "https://127.0.0.1/index/hook/on_flow_report"; 472 | /// 473 | /// 访问http文件鉴权事件,置空则关闭鉴权 474 | /// 475 | [JsonPropertyName("on_http_access")] 476 | public virtual string OnHttpAccess { get; set; } = "https://127.0.0.1/index/hook/on_http_access"; 477 | /// 478 | /// 播放鉴权事件,置空则关闭鉴权 479 | /// 480 | [JsonPropertyName("on_play")] 481 | public virtual string OnPlay { get; set; } = "https://127.0.0.1/index/hook/on_play"; 482 | /// 483 | /// 推流鉴权事件,置空则关闭鉴权 484 | /// 485 | [JsonPropertyName("on_publish")] 486 | public virtual string OnPublish { get; set; } = "https://127.0.0.1/index/hook/on_publish"; 487 | /// 488 | /// 录制mp4切片完成事件 489 | /// 490 | [JsonPropertyName("on_record_mp4")] 491 | public virtual string OnRecordMp4 { get; set; } = "https://127.0.0.1/index/hook/on_record_mp4"; 492 | /// 493 | /// 录制 hls ts 切片完成事件 494 | /// 495 | [JsonPropertyName("on_record_ts")] 496 | public virtual string NnRecordTs { get; set; } = "https://127.0.0.1/index/hook/on_record_ts"; 497 | /// 498 | /// rtsp播放鉴权事件,此事件中比对rtsp的用户名密码 499 | /// 500 | [JsonPropertyName("on_rtsp_auth")] 501 | public virtual string NnRtspAuth { get; set; } = "https://127.0.0.1/index/hook/on_rtsp_auth"; 502 | /// 503 | /// rtsp播放是否开启专属鉴权事件,置空则关闭rtsp鉴权。rtsp播放鉴权还支持url方式鉴权 504 | /// 建议开发者统一采用url参数方式鉴权,rtsp用户名密码鉴权一般在设备上用的比较多 505 | /// 开启rtsp专属鉴权后,将不再触发on_play鉴权事件 506 | /// 507 | [JsonPropertyName("on_rtsp_realm")] 508 | public virtual string OnRtspRealm { get; set; } = "https://127.0.0.1/index/hook/on_rtsp_realm"; 509 | /// 510 | /// 远程telnet调试鉴权事件 511 | /// 512 | [JsonPropertyName("on_shell_login")] 513 | public virtual string OnShellLogin { get; set; } = "https://127.0.0.1/index/hook/on_shell_login"; 514 | /// 515 | /// 直播流注册或注销事件 516 | /// 517 | [JsonPropertyName("on_stream_changed")] 518 | public virtual string OnStreamChanged { get; set; } = "https://127.0.0.1/index/hook/on_stream_changed"; 519 | /// 520 | /// 无人观看流事件,通过该事件,可以选择是否关闭无人观看的流。配合general.streamNoneReaderDelayMS选项一起使用 521 | /// 522 | [JsonPropertyName("on_stream_none_reader")] 523 | public virtual string OnStreamNoneReader { get; set; } = "https://127.0.0.1/index/hook/on_stream_none_reader"; 524 | /// 525 | /// 播放时,未找到流事件,通过配合hook.on_stream_none_reader事件可以完成按需拉流 526 | /// 527 | [JsonPropertyName("on_stream_not_found")] 528 | public virtual string OnStreamNotFound { get; set; } = "https://127.0.0.1/index/hook/on_stream_not_found"; 529 | /// 530 | /// 服务器启动报告,可以用于服务器的崩溃重启事件监听 531 | /// 532 | [JsonPropertyName("on_server_started")] 533 | public virtual string OnServerStarted { get; set; } = "https://127.0.0.1/index/hook/on_server_started"; 534 | /// 535 | /// server保活上报 536 | /// 537 | [JsonPropertyName("on_server_keepalive")] 538 | public virtual string OnServerKeepalive { get; set; } = "https://127.0.0.1/index/hook/on_server_keepalive"; 539 | /// 540 | /// hook api最大等待回复时间,单位秒 541 | /// 542 | public virtual int TimeoutSec { get; set; } = 10; 543 | /// 544 | /// keepalive hook触发间隔,单位秒,float类型 545 | /// 546 | [JsonPropertyName("alive_interval")] 547 | public virtual float AliveInterval { get; set; } = 10.0f; 548 | } 549 | 550 | #endregion hook config 551 | 552 | #region Http Config 553 | 554 | public interface IHttpConfig 555 | { 556 | /// 557 | /// http服务器字符编码,windows上默认gb2312 558 | /// 559 | [JsonPropertyName("charSet")] 560 | public string CharSet { get; set; } 561 | /// 562 | /// http链接超时时间 563 | /// 564 | [JsonPropertyName("keepAliveSecond")] 565 | public int KeepAliveSecond { get; set; } 566 | /// 567 | /// http请求体最大字节数,如果post的body太大,则不适合缓存body在内存 568 | /// 569 | [JsonPropertyName("maxReqSize")] 570 | public int MaxReqSize { get; set; } 571 | 572 | /// 573 | /// 404网页内容,用户可以自定义404网页 574 | /// 575 | [JsonPropertyName("notFound")] 576 | public string NotFound { get; set; } 577 | /// 578 | /// http服务器监听端口 579 | /// 580 | [JsonPropertyName("port")] 581 | public int Port { get; set; } 582 | /// 583 | /// http文件服务器根目录 584 | /// 可以为相对(相对于本可执行程序目录)或绝对路径 585 | /// 586 | [JsonPropertyName("rootPath")] 587 | public string RootPath { get; set; } 588 | /// 589 | /// http文件服务器读文件缓存大小,单位BYTE,调整该参数可以优化文件io性能 590 | /// 591 | [JsonPropertyName("sendBufSize")] 592 | public int SendBufSize { get; set; } 593 | /// 594 | /// https服务器监听端口 595 | /// 596 | [JsonPropertyName("sslport")] 597 | public int Sslport { get; set; } 598 | /// 599 | /// 是否显示文件夹菜单,开启后可以浏览文件夹 600 | /// 601 | [JsonPropertyName("dirMenu")] 602 | [JsonConverter(typeof(ZLBoolConverter))] 603 | public bool DirMenu { get; set; } 604 | /// 605 | /// 虚拟目录, 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开 606 | /// 例如赋值为 app_a,/path/to/a;app_b,/path/to/b 那么 607 | /// 访问 http://127.0.0.1/app_a/file_a 对应的文件路径为 /path/to/a/file_a 608 | /// 访问 http://127.0.0.1/app_b/file_b 对应的文件路径为 /path/to/b/file_b 609 | /// 访问其他http路径,对应的文件路径还是在rootPath内 610 | /// 611 | [JsonPropertyName("virtualPath")] 612 | public string VirtualPath { get; set; } 613 | } 614 | 615 | public class HttpConfig : IHttpConfig 616 | { 617 | /// 618 | /// http服务器字符编码,windows上默认gb2312 619 | /// 620 | [JsonPropertyName("charSet")] 621 | public virtual string CharSet { get; set; } = "utf-8"; 622 | /// 623 | /// http链接超时时间 624 | /// 625 | [JsonPropertyName("keepAliveSecond")] 626 | public virtual int KeepAliveSecond { get; set; } = 30; 627 | /// 628 | /// http请求体最大字节数,如果post的body太大,则不适合缓存body在内存 629 | /// 630 | [JsonPropertyName("maxReqSize")] 631 | public virtual int MaxReqSize { get; set; } = 40960; 632 | 633 | /// 634 | /// 404网页内容,用户可以自定义404网页 635 | /// 636 | [JsonPropertyName("notFound")] 637 | public virtual string NotFound { get; set; } = "404 Not Found

您访问的资源不存在!


ZLMediaKit-4.0
"; 638 | /// 639 | /// http服务器监听端口 640 | /// 641 | [JsonPropertyName("port")] 642 | public virtual int Port { get; set; } = 80; 643 | /// 644 | /// http文件服务器根目录 645 | /// 可以为相对(相对于本可执行程序目录)或绝对路径 646 | /// 647 | [JsonPropertyName("rootPath")] 648 | public virtual string RootPath { get; set; } = "./www"; 649 | /// 650 | /// http文件服务器读文件缓存大小,单位BYTE,调整该参数可以优化文件io性能 651 | /// 652 | [JsonPropertyName("sendBufSize")] 653 | public virtual int SendBufSize { get; set; } = 65536; 654 | /// 655 | /// https服务器监听端口 656 | /// 657 | [JsonPropertyName("sslport")] 658 | public virtual int Sslport { get; set; } = 443; 659 | /// 660 | /// 是否显示文件夹菜单,开启后可以浏览文件夹 661 | /// 662 | [JsonPropertyName("dirMenu")] 663 | [JsonConverter(typeof(ZLBoolConverter))] 664 | public virtual bool DirMenu { get; set; } = true; 665 | /// 666 | /// 虚拟目录, 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开 667 | /// 例如赋值为 app_a,/path/to/a;app_b,/path/to/b 那么 668 | /// 访问 http://127.0.0.1/app_a/file_a 对应的文件路径为 /path/to/a/file_a 669 | /// 访问 http://127.0.0.1/app_b/file_b 对应的文件路径为 /path/to/b/file_b 670 | /// 访问其他http路径,对应的文件路径还是在rootPath内 671 | /// 672 | [JsonPropertyName("virtualPath")] 673 | public virtual string VirtualPath { get; set; } 674 | } 675 | 676 | #endregion http Config 677 | 678 | #region multicast config 679 | 680 | public interface IMulticastConfig 681 | { 682 | /// 683 | /// rtp组播截止组播ip地址 684 | /// 685 | [JsonPropertyName("addrMax")] 686 | public string AddrMax { get; set; } 687 | /// 688 | /// rtp组播起始组播ip地址 689 | /// 690 | [JsonPropertyName("addrMin")] 691 | public string AddrMin { get; set; } 692 | /// 693 | /// 组播udp ttl 694 | /// 695 | [JsonPropertyName("udpTTL")] 696 | public int UdpTTL { get; set; } 697 | } 698 | 699 | public class MulticastConfig : IMulticastConfig 700 | { 701 | /// 702 | /// rtp组播截止组播ip地址 703 | /// 704 | [JsonPropertyName("addrMax")] 705 | public virtual string AddrMax { get; set; } = "239.255.255.255"; 706 | /// 707 | /// rtp组播起始组播ip地址 708 | /// 709 | [JsonPropertyName("addrMin")] 710 | public virtual string AddrMin { get; set; } = "239.0.0.0"; 711 | /// 712 | /// 组播udp ttl 713 | /// 714 | [JsonPropertyName("udpTTL")] 715 | public virtual int UdpTTL { get; set; } = 64; 716 | } 717 | 718 | #endregion multicast config 719 | 720 | #region record config 721 | 722 | public interface IRecordConfig 723 | { 724 | /// 725 | /// mp4录制或mp4点播的应用名,通过限制应用名,可以防止随意点播 点播的文件必须放置在此文件夹下 726 | /// 727 | [JsonPropertyName("appName")] 728 | public string AppName { get; set; } 729 | /// 730 | /// mp4录制写文件缓存,单位BYTE,调整参数可以提高文件io性能 731 | /// 732 | [JsonPropertyName("fileBufSize")] 733 | public int FileBufSize { get; set; } 734 | /// 735 | /// mp4录制保存、mp4点播根路径 ,可以为相对(相对于本可执行程序目录)或绝对路径 736 | /// 737 | [JsonPropertyName("filePath")] 738 | public string FilePath { get; set; } 739 | /// 740 | /// mp4录制切片时间,单位秒 741 | /// 742 | [JsonPropertyName("fileSecond")] 743 | public int FileSecond { get; set; } 744 | /// 745 | /// mp4点播每次流化数据量,单位毫秒, 减少该值可以让点播数据发送量更平滑,增大该值则更节省cpu资源 746 | /// 747 | [JsonPropertyName("sampleMS")] 748 | public int SampleMS { get; set; } 749 | /// 750 | /// mp4录制完成后是否进行二次关键帧索引写入头部 751 | /// 752 | [JsonPropertyName("fastStart")] 753 | [JsonConverter(typeof(ZLBoolConverter))] 754 | public bool FastStart { get; set; } 755 | /// 756 | /// MP4点播(rtsp/rtmp/http-flv/ws-flv)是否循环播放文件 757 | /// 758 | [JsonPropertyName("fileRepeat")] 759 | [JsonConverter(typeof(ZLBoolConverter))] 760 | public bool FileRepeat { get; set; } 761 | } 762 | 763 | public class RecordConfig : IRecordConfig 764 | { 765 | /// 766 | /// mp4录制或mp4点播的应用名,通过限制应用名,可以防止随意点播 点播的文件必须放置在此文件夹下 767 | /// 768 | [JsonPropertyName("appName")] 769 | public virtual string AppName { get; set; } = "record"; 770 | /// 771 | /// mp4录制写文件缓存,单位BYTE,调整参数可以提高文件io性能 772 | /// 773 | [JsonPropertyName("fileBufSize")] 774 | public virtual int FileBufSize { get; set; } = 65536; 775 | /// 776 | /// mp4录制保存、mp4点播根路径 ,可以为相对(相对于本可执行程序目录)或绝对路径 777 | /// 778 | [JsonPropertyName("filePath")] 779 | public virtual string FilePath { get; set; } = "./www"; 780 | /// 781 | /// mp4录制切片时间,单位秒 782 | /// 783 | [JsonPropertyName("fileSecond")] 784 | public virtual int FileSecond { get; set; } = 3600; 785 | /// 786 | /// mp4点播每次流化数据量,单位毫秒, 减少该值可以让点播数据发送量更平滑,增大该值则更节省cpu资源 787 | /// 788 | [JsonPropertyName("sampleMS")] 789 | public virtual int SampleMS { get; set; } = 500; 790 | /// 791 | /// mp4录制完成后是否进行二次关键帧索引写入头部 792 | /// 793 | [JsonPropertyName("fastStart")] 794 | public virtual bool FastStart { get; set; } = false; 795 | /// 796 | /// MP4点播(rtsp/rtmp/http-flv/ws-flv)是否循环播放文件 797 | /// 798 | [JsonPropertyName("fileRepeat")] 799 | [JsonConverter(typeof(ZLBoolConverter))] 800 | public virtual bool FileRepeat { get; set; } = false; 801 | } 802 | 803 | #endregion record config 804 | 805 | #region Rtmp config 806 | 807 | public interface IRtmpConfig 808 | { 809 | /// 810 | /// rtmp必须在此时间内完成握手,否则服务器会断开链接,单位秒 811 | /// 812 | [JsonPropertyName("handshakeSecond")] 813 | public int HandshakeSecond { get; set; } 814 | /// 815 | /// rtmp超时时间,如果该时间内未收到客户端的数据, 或者tcp发送缓存超过这个时间,则会断开连接,单位秒 816 | /// 817 | [JsonPropertyName("keepAliveSecond")] 818 | public int KeepAliveSecond { get; set; } 819 | /// 820 | /// 在接收rtmp推流时,是否重新生成时间戳(很多推流器的时间戳着实很烂) 821 | /// 822 | [JsonPropertyName("modifyStamp")] 823 | [JsonConverter(typeof(ZLBoolConverter))] 824 | public bool ModifyStamp { get; set; } 825 | /// 826 | /// rtmp服务器监听端口 827 | /// 828 | [JsonPropertyName("port")] 829 | public int Port { get; set; } 830 | /// 831 | /// rtmps服务器监听地址 832 | /// 833 | [JsonPropertyName("sslport")] 834 | public int Sslport { get; set; } 835 | } 836 | 837 | public class RtmpConfig : IRtmpConfig 838 | { 839 | /// 840 | /// rtmp必须在此时间内完成握手,否则服务器会断开链接,单位秒 841 | /// 842 | [JsonPropertyName("handshakeSecond")] 843 | public virtual int HandshakeSecond { get; set; } = 15; 844 | /// 845 | /// rtmp超时时间,如果该时间内未收到客户端的数据, 或者tcp发送缓存超过这个时间,则会断开连接,单位秒 846 | /// 847 | [JsonPropertyName("keepAliveSecond")] 848 | public virtual int KeepAliveSecond { get; set; } = 15; 849 | /// 850 | /// 在接收rtmp推流时,是否重新生成时间戳(很多推流器的时间戳着实很烂) 851 | /// 852 | [JsonPropertyName("modifyStamp")] 853 | [JsonConverter(typeof(ZLBoolConverter))] 854 | public virtual bool ModifyStamp { get; set; } = false; 855 | /// 856 | /// rtmp服务器监听端口 857 | /// 858 | [JsonPropertyName("port")] 859 | public virtual int Port { get; set; } = 1935; 860 | /// 861 | /// rtmps服务器监听地址 862 | /// 863 | [JsonPropertyName("sslport")] 864 | public virtual int Sslport { get; set; } = 0; 865 | } 866 | 867 | #endregion Rtmp config 868 | 869 | #region rtp Config 870 | 871 | public interface IRtpConfig 872 | { 873 | /// 874 | /// 频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400 875 | /// 加大该值会明显增加直播延时 876 | /// 877 | [JsonPropertyName("audioMtuSize")] 878 | public int AudioMtuSize { get; set; } 879 | /// 880 | /// 视频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400 881 | /// 882 | [JsonPropertyName("videoMtuSize")] 883 | public int VideoMtuSize { get; set; } 884 | /// 885 | /// rtp包最大长度限制,单位KB,主要用于识别TCP上下文破坏时,获取到错误的rtp 886 | /// 887 | [JsonPropertyName("rtpMaxSize")] 888 | public int RtpMaxSize { get; set; } 889 | } 890 | 891 | public class RtpConfig : IRtpConfig 892 | { 893 | /// 894 | /// 频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400 895 | /// 加大该值会明显增加直播延时 896 | /// 897 | [JsonPropertyName("audioMtuSize")] 898 | public virtual int AudioMtuSize { get; set; } = 600; 899 | /// 900 | /// 视频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400 901 | /// 902 | [JsonPropertyName("videoMtuSize")] 903 | public virtual int VideoMtuSize { get; set; } = 1400; 904 | /// 905 | /// rtp包最大长度限制,单位KB,主要用于识别TCP上下文破坏时,获取到错误的rtp 906 | /// 907 | [JsonPropertyName("rtpMaxSize")] 908 | public virtual int RtpMaxSize { get; set; } = 10; 909 | } 910 | 911 | #endregion rtp config 912 | 913 | #region RtpProxy config 914 | public interface IRtpProxyConfig 915 | { 916 | /// 917 | /// 导出调试数据(包括rtp/ps/h264)至该目录,置空则关闭数据导出 918 | /// 919 | [JsonPropertyName("dumpDir")] 920 | public string DumpDir { get; set; } 921 | /// 922 | /// udp和tcp代理服务器,支持rtp(必须是ts或ps类型)代理 923 | /// 924 | [JsonPropertyName("port")] 925 | public int Port { get; } 926 | /// 927 | /// rtp超时时间,单位秒 928 | /// 929 | [JsonPropertyName("timeoutSec")] 930 | public int TimeoutSec { get; set; } 931 | } 932 | public class RtpProxyConfig : IRtpProxyConfig 933 | { 934 | /// 935 | /// 导出调试数据(包括rtp/ps/h264)至该目录,置空则关闭数据导出 936 | /// 937 | [JsonPropertyName("dumpDir")] 938 | public virtual string DumpDir { get; set; } 939 | /// 940 | /// udp和tcp代理服务器,支持rtp(必须是ts或ps类型)代理 941 | /// 942 | [JsonPropertyName("port")] 943 | public virtual int Port { get; set; } = 10000; 944 | /// 945 | /// rtp超时时间,单位秒 946 | /// 947 | [JsonPropertyName("timeoutSec")] 948 | public virtual int TimeoutSec { get; set; } = 15; 949 | } 950 | #endregion RtpProxy config 951 | 952 | #region Rtc config 953 | 954 | public interface IRtcConfig 955 | { 956 | /// 957 | /// rtc播放推流、播放超时时间 958 | /// 959 | [JsonPropertyName("timeoutSec")] 960 | public int TimeoutSec { get; set; } 961 | /// 962 | /// 本机对rtc客户端的可见ip,作为服务器时一般为公网ip,置空时,会自动获取网卡ip 963 | /// 964 | [JsonPropertyName("externIP")] 965 | public string ExternIP { get; set; } 966 | /// 967 | /// rtc udp服务器监听端口号,所有rtc客户端将通过该端口传输stun/dtls/srtp/srtcp数据, 968 | /// 该端口是多线程的,同时支持客户端网络切换导致的连接迁移 969 | /// 需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致 970 | /// 971 | [JsonPropertyName("port")] 972 | public int Port { get; set; } 973 | /// 974 | /// 设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质 975 | /// 目前已经实现twcc自动调整码率,关闭remb根据真实网络状况调整码率 976 | /// 977 | [JsonPropertyName("rembBitRate")] 978 | public int RembBitRate { get; set; } 979 | /// 980 | /// rtc支持的音频codec类型,在前面的优先级更高 981 | /// 以下范例为所有支持的音频codec 982 | /// 983 | [JsonPropertyName("preferredCodecA")] 984 | public string PreferredCodecA { get; set; } 985 | /// 986 | /// rtc支持的视频codec类型,在前面的优先级更高 987 | /// 以下范例为所有支持的视频codec 988 | /// 989 | [JsonPropertyName("preferredCodecV")] 990 | public string PreferredCodecV { get; set; } 991 | } 992 | 993 | public class RtcConfig : IRtcConfig 994 | { 995 | /// 996 | /// rtc播放推流、播放超时时间 997 | /// 998 | [JsonPropertyName("timeoutSec")] 999 | public virtual int TimeoutSec { get; set; } = 15; 1000 | /// 1001 | /// 本机对rtc客户端的可见ip,作为服务器时一般为公网ip,置空时,会自动获取网卡ip 1002 | /// 1003 | [JsonPropertyName("externIP")] 1004 | public virtual string ExternIP { get; set; } 1005 | /// 1006 | /// rtc udp服务器监听端口号,所有rtc客户端将通过该端口传输stun/dtls/srtp/srtcp数据, 1007 | /// 该端口是多线程的,同时支持客户端网络切换导致的连接迁移 1008 | /// 需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致 1009 | /// 1010 | [JsonPropertyName("port")] 1011 | public virtual int Port { get; set; } = 8000; 1012 | /// 1013 | /// 设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质 1014 | /// 目前已经实现twcc自动调整码率,关闭remb根据真实网络状况调整码率 1015 | /// 1016 | [JsonPropertyName("rembBitRate")] 1017 | public virtual int RembBitRate { get; set; } = 0; 1018 | /// 1019 | /// rtc支持的音频codec类型,在前面的优先级更高 1020 | /// 以下范例为所有支持的音频codec 1021 | /// 1022 | [JsonPropertyName("preferredCodecA")] 1023 | public virtual string PreferredCodecA { get; set; } = "PCMU,PCMA,opus,mpeg4-generic"; 1024 | /// 1025 | /// rtc支持的视频codec类型,在前面的优先级更高 1026 | /// 以下范例为所有支持的视频codec 1027 | /// 1028 | [JsonPropertyName("preferredCodecV")] 1029 | public virtual string PreferredCodecV { get; set; } = "H264, H265, AV1X, VP9, VP8"; 1030 | } 1031 | 1032 | #endregion rtc config 1033 | 1034 | #region rtsp config 1035 | 1036 | public interface IRtspConfig 1037 | { 1038 | /// 1039 | /// rtsp专有鉴权方式是采用base64还是md5方式 1040 | /// 1041 | [JsonPropertyName("authBasic")] 1042 | [JsonConverter(typeof(ZLBoolConverter))] 1043 | public bool AuthBasic { get; set; } 1044 | /// 1045 | /// rtsp拉流、推流代理是否是直接代理模式 1046 | /// 直接代理后支持任意编码格式,但是会导致GOP缓存无法定位到I帧,可能会导致开播花屏 1047 | /// 并且如果是tcp方式拉流,如果rtp大于mtu会导致无法使用udp方式代理 1048 | /// 假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理 1049 | /// 如果你是rtsp推拉流,但是rtc播放,也建议关闭直接代理模式, 1050 | /// 因为直接代理时,rtp中可能没有sps pps,会导致rtc无法播放 1051 | /// 默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的 1052 | /// 1053 | [JsonPropertyName("directProxy")] 1054 | [JsonConverter(typeof(ZLBoolConverter))] 1055 | public bool DirectProxy { get; set; } 1056 | /// 1057 | /// rtsp必须在此时间内完成握手,否则服务器会断开链接,单位秒 1058 | /// 1059 | [JsonPropertyName("handshakeSecond")] 1060 | public int HandshakeSecond { get; set; } 1061 | /// 1062 | /// rtsp超时时间,如果该时间内未收到客户端的数据, 1063 | /// 或者tcp发送缓存超过这个时间,则会断开连接,单位秒 1064 | /// 1065 | [JsonPropertyName("keepAliveSecond")] 1066 | public int KeepAliveSecond { get; set; } 1067 | /// 1068 | /// rtsp服务器监听地址 1069 | /// 1070 | [JsonPropertyName("port")] 1071 | public int Port { get; set; } 1072 | /// 1073 | /// rtsps服务器监听地址 1074 | /// 1075 | [JsonPropertyName("sslport")] 1076 | public int Sslport { get; set; } 1077 | } 1078 | 1079 | public class RtspConfig : IRtspConfig 1080 | { 1081 | /// 1082 | /// rtsp专有鉴权方式是采用base64还是md5方式 1083 | /// 1084 | [JsonPropertyName("authBasic")] 1085 | [JsonConverter(typeof(ZLBoolConverter))] 1086 | public virtual bool AuthBasic { get; set; } = false; 1087 | /// 1088 | /// rtsp拉流、推流代理是否是直接代理模式 1089 | /// 直接代理后支持任意编码格式,但是会导致GOP缓存无法定位到I帧,可能会导致开播花屏 1090 | /// 并且如果是tcp方式拉流,如果rtp大于mtu会导致无法使用udp方式代理 1091 | /// 假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理 1092 | /// 如果你是rtsp推拉流,但是rtc播放,也建议关闭直接代理模式, 1093 | /// 因为直接代理时,rtp中可能没有sps pps,会导致rtc无法播放 1094 | /// 默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的 1095 | /// 1096 | [JsonPropertyName("directProxy")] 1097 | [JsonConverter(typeof(ZLBoolConverter))] 1098 | public virtual bool DirectProxy { get; set; } = true; 1099 | /// 1100 | /// rtsp必须在此时间内完成握手,否则服务器会断开链接,单位秒 1101 | /// 1102 | [JsonPropertyName("handshakeSecond")] 1103 | public virtual int HandshakeSecond { get; set; } = 15; 1104 | /// 1105 | /// rtsp超时时间,如果该时间内未收到客户端的数据, 1106 | /// 或者tcp发送缓存超过这个时间,则会断开连接,单位秒 1107 | /// 1108 | [JsonPropertyName("keepAliveSecond")] 1109 | public virtual int KeepAliveSecond { get; set; } = 15; 1110 | /// 1111 | /// rtsp服务器监听地址 1112 | /// 1113 | [JsonPropertyName("port")] 1114 | public virtual int Port { get; set; } = 554; 1115 | /// 1116 | /// rtsps服务器监听地址 1117 | /// 1118 | [JsonPropertyName("sslport")] 1119 | public virtual int Sslport { get; set; } = 0; 1120 | } 1121 | 1122 | #endregion rtsp config 1123 | 1124 | #region shell config 1125 | 1126 | public interface IShellConfig 1127 | { 1128 | /// 1129 | /// 调试telnet服务器接受最大bufffer大小 1130 | /// 1131 | [JsonPropertyName("maxReqSize")] 1132 | public int MaxReqSize { get; set; } 1133 | /// 1134 | /// 调试telnet服务器监听端口 1135 | /// 1136 | [JsonPropertyName("port")] 1137 | public int Port { get; set; } 1138 | } 1139 | 1140 | public class ShellConfig : IShellConfig 1141 | { 1142 | /// 1143 | /// 调试telnet服务器接受最大bufffer大小 1144 | /// 1145 | [JsonPropertyName("maxReqSize")] 1146 | public virtual int MaxReqSize { get; set; } = 1024; 1147 | /// 1148 | /// 调试telnet服务器监听端口 1149 | /// 1150 | [JsonPropertyName("port")] 1151 | public virtual int Port { get; set; } = 0; 1152 | } 1153 | 1154 | #endregion shell config 1155 | } 1156 | --------------------------------------------------------------------------------