Example #1
0
        /// <summary>
        /// 开启
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private static async Task <StartLiveDataInfo> StartLive(User user, LiveSetting liveSetting)
        {
            try
            {
                //先停止历史直播
                if (await LiveApi.StopLive(user))
                {
                    GlobalSettings.Logger.LogInfo("尝试关闭历史直播...成功!");
                }
                //修改直播间名称
                if (await LiveApi.UpdateLiveRoomName(user, liveSetting.LiveRoomName))
                {
                    GlobalSettings.Logger.LogInfo($"成功修改直播间名称。直播间名称:{liveSetting.LiveRoomName}");
                }
                StartLiveDataInfo liveInfo = await LiveApi.StartLive(user, liveSetting.LiveCategory);

                if (liveInfo != null)
                {
                    GlobalSettings.Logger.LogInfo("开启直播成功!");
                    GlobalSettings.Logger.LogInfo($"我的直播间地址:http://live.bilibili.com/{liveInfo.RoomId}");
                    GlobalSettings.Logger.LogInfo($"推流地址:{liveInfo.Rtmp.Addr}{liveInfo.Rtmp.Code}");
                }
                return(liveInfo);
            }
            catch (Exception ex)
            {
                GlobalSettings.Logger.LogError($"开启直播失败!错误:{ex.Message}");
                return(null);
            }
        }
Example #2
0
        /// <summary>
        /// 开启
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private async Task <StartLiveDataInfo> StartLive()
        {
            try
            {
                //修改直播间名称
                if (await _liveApi.UpdateLiveRoomName(this._account, _config.LiveSetting.LiveRoomName))
                {
                    _logger.LogInformation($"成功修改直播间名称,直播间名称:{_config.LiveSetting.LiveRoomName}");
                }
                //更新分类
                if (await _liveApi.UpdateLiveCategory(this._account, _config.LiveSetting.LiveCategory))
                {
                    _logger.LogInformation($"成功修改直播间分类,直播间分类ID:{_config.LiveSetting.LiveCategory}");
                }
                StartLiveDataInfo liveInfo = await _liveApi.StartLive(this._account, _config.LiveSetting.LiveCategory);

                if (liveInfo == null)
                {
                    throw new Exception("获取直播信息失败!");
                }
                _logger.LogInformation("开启直播成功!");
                _logger.LogInformation($"我的直播间地址:http://live.bilibili.com/{liveInfo.RoomId}");
                _logger.LogInformation($"推流地址:{liveInfo.Rtmp.Addr}{liveInfo.Rtmp.Code}");
                return(liveInfo);
            }
            catch (Exception ex)
            {
                _logger.LogError($"开启直播失败!错误:{ex.Message}", ex);
                return(null);
            }
        }
Example #3
0
        /// <summary>
        /// 开启
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        private static async Task <bool> StartLive(User user)
        {
            try
            {
                //加载配置文件
                LiveSetting liveSetting = LoadLiveSettingConfig();

                //先停止历史直播
                if (await LiveApi.StopLive(user))
                {
                    GlobalSettings.Logger.LogInfo("尝试关闭历史直播...成功!");
                }
                //修改直播间名称
                if (await LiveApi.UpdateLiveRoomName(user, liveSetting.LiveRoomName))
                {
                    GlobalSettings.Logger.LogInfo($"成功修改直播间名称。直播间名称:{liveSetting.LiveRoomName}");
                }
                StartLiveDataInfo liveInfo = await LiveApi.StartLive(user, liveSetting.LiveCategory);

                if (liveInfo != null)
                {
                    GlobalSettings.Logger.LogInfo("开启直播成功!");
                    GlobalSettings.Logger.LogInfo($"我的直播间地址:http://live.bilibili.com/{liveInfo.RoomId}");
                    GlobalSettings.Logger.LogInfo($"推流地址:{liveInfo.Rtmp.Addr}{liveInfo.Rtmp.Code}");
                }
                //开始使用ffmpeg推流直播
                StartPublish(liveSetting, $"{liveInfo.Rtmp.Addr}{liveInfo.Rtmp.Code}");
                return(true);
            }
            catch (Exception ex)
            {
                GlobalSettings.Logger.LogError($"开启直播失败!错误:{ex.Message}");
                return(false);
            }
        }
Example #4
0
        /// <summary>
        /// 开始推流
        /// </summary>
        /// <param name="setting"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private static async Task <bool> StartPublish(User user, LiveSetting setting, string url)
        {
            try
            {
                if (string.IsNullOrEmpty(setting.CmdString))
                {
                    throw new Exception("CMD string can not null.");
                }
                if (setting.CmdString.IndexOf("[[URL]]") < 0)
                {
                    throw new Exception("Cmd args cannot find '[[URL]]' mark.");
                }
                setting.CmdString = setting.CmdString.Replace("[[URL]]", $"\"{url}\"");
                int firstNullChar = setting.CmdString.IndexOf((char)32);
                if (firstNullChar < 0)
                {
                    throw new Exception("Cannot find cmd process name(look like 'ping 127.0.0.1','ping' is process name).");
                }
                string cmdName = setting.CmdString.Substring(0, firstNullChar);
                string cmdArgs = setting.CmdString.Substring(firstNullChar);
                if (string.IsNullOrEmpty(cmdArgs))
                {
                    throw new Exception("Cmd args cannot null.");
                }
                var psi = new ProcessStartInfo
                {
                    FileName  = cmdName,
                    Arguments = cmdArgs,
                    RedirectStandardOutput = true,
                    UseShellExecute        = false,
                    CreateNoWindow         = RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
                };
                bool isAutoRestart = true;
                while (isAutoRestart)
                {
                    isAutoRestart = setting.AutoRestart;
                    while (!await NetworkTools.NetworkCheck())
                    {
                        GlobalSettings.Logger.LogInfo($"Wait for network...");
                        await Task.Delay(3000);
                    }
                    if (!await LiveRoomStateCheck(user))
                    {
                        GlobalSettings.Logger.LogInfo($"Start live failed...");
                        return(false);
                    }
                    StartLiveDataInfo liveInfo = await StartLive(user, setting);

                    if (liveInfo == null)
                    {
                        GlobalSettings.Logger.LogInfo($"Start live failed...");
                        return(false);
                    }
                    //启动
                    var proc = Process.Start(psi);
                    if (proc == null)
                    {
                        throw new Exception("Can not exec set cmd.");
                    }
                    else
                    {
                        //开始读取命令输出
                        using (var sr = proc.StandardOutput)
                        {
                            while (!sr.EndOfStream)
                            {
                                GlobalSettings.Logger.LogInfo(sr.ReadLine());
                            }
                            if (!proc.HasExited)
                            {
                                proc.Kill();
                            }
                        }
                        //退出检测
                        if (!Console.IsInputRedirected)
                        {
                            Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs eventArgs) =>
                            {
                                isAutoRestart = false;
                            };
                        }
                        if (isAutoRestart)
                        {
                            GlobalSettings.Logger.LogInfo($"Cmd exited. Auto restart.");
                        }
                        else
                        {
                            GlobalSettings.Logger.LogInfo($"Cmd exited.");
                        }
                    }
                    if (isAutoRestart)
                    {
                        GlobalSettings.Logger.LogInfo($"Wait for restart...");
                        //如果开启了自动重试,那么等待60s后再次尝试
                        await Task.Delay(60000);
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                GlobalSettings.Logger.LogError(ex.Message);
                return(false);
            }
        }
Example #5
0
        /// <summary>
        /// 开始推流
        /// </summary>
        /// <param name="setting"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private async Task <bool> UseFFmpegLive(string url)
        {
            try
            {
                if (string.IsNullOrEmpty(_config.LiveSetting.FFmpegCmd))
                {
                    throw new Exception("推流命令不能为空。");
                }
                int markIndex = _config.LiveSetting.FFmpegCmd.IndexOf("[[URL]]");
                if (markIndex < 5)
                {
                    throw new Exception("在填写的命令中未找到 '[[URL]]'标记。");
                }
                if (_config.LiveSetting.FFmpegCmd[markIndex - 1] == '\"')
                {
                    throw new Exception(" '[[URL]]'标记前后无需“\"”。");
                }
                string newCmd        = _config.LiveSetting.FFmpegCmd.Replace("[[URL]]", $"\"{url}\"");
                int    firstNullChar = newCmd.IndexOf((char)32);
                if (firstNullChar < 0)
                {
                    throw new Exception("无法获取命令执行名称,比如在命令ffmpeg -version中,无法获取ffmpeg。");
                }
                string cmdName = newCmd.Substring(0, firstNullChar);
                string cmdArgs = newCmd.Substring(firstNullChar);
                if (string.IsNullOrEmpty(cmdArgs))
                {
                    throw new Exception("命令参数不能为空!");
                }

                var psi = new ProcessStartInfo
                {
                    FileName  = cmdName,
                    Arguments = cmdArgs,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = false,
                    UseShellExecute        = false,
                    CreateNoWindow         = RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
                };
                bool isAutoRestart = true;
                while (isAutoRestart)
                {
                    isAutoRestart = _config.LiveSetting.AutoRestart;
                    //check network
                    while (!await NetworkUtil.NetworkCheck())
                    {
                        _logger.LogWarning($"网络连接已断开,将在10秒后重新检查网络连接...");
                        await Task.Delay(10000);
                    }
                    //check token is available
                    if (!ByPassword.IsTokenAvailable(_account.AccessToken))
                    {
                        await LoginToBilibili();
                    }
                    //start live
                    StartLiveDataInfo liveInfo = await StartLive();

                    if (liveInfo == null)
                    {
                        _logger.LogError($"开启B站直播间失败,无法获取推流地址。");
                        return(false);
                    }
                    _logger.LogInformation("正在初始化推流指令...");
                    //启动
                    using (var proc = Process.Start(psi))
                    {
                        if (proc == null || proc.Id <= 0)
                        {
                            throw new Exception("无法执行指定的推流指令,请检查FFmpegCmd是否填写正确。");
                        }
                        //退出检测
                        if (!Console.IsInputRedirected)
                        {
                            Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs eventArgs) =>
                            {
                                isAutoRestart = false;
                            };
                        }
                        await proc.WaitForExitAsync();

                        if (isAutoRestart)
                        {
                            _logger.LogWarning($"FFmpeg异常退出,将在60秒后重试推流。");
                        }
                        else
                        {
                            _logger.LogWarning($"FFmpeg异常退出。");
                        }
                    }
                    if (isAutoRestart)
                    {
                        _logger.LogWarning($"等待重新推流...");
                        //如果开启了自动重试,那么等待60s后再次尝试
                        await Task.Delay(60000);
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.Message, ex);
                return(false);
            }
        }