LiveStudio.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\admin\model\live;
  12. /**
  13. * 直播信息表
  14. */
  15. use app\admin\model\order\StoreOrder;
  16. use app\admin\model\user\User;
  17. use basic\ModelBasic;
  18. use traits\ModelTrait;
  19. use \GatewayWorker\Lib\Gateway;
  20. use service\SystemConfigService;
  21. class LiveStudio extends ModelBasic
  22. {
  23. use ModelTrait;
  24. protected $insert = ['add_time'];
  25. //直播间号码不能连续存在的数字
  26. protected static $taboo = ['4', '38', '13', '14', '7', '7086', '5454', '3838', '36', '69', '47', '18'];
  27. protected function setAddTimeAttr()
  28. {
  29. return time();
  30. }
  31. /**
  32. * 生成并检查直播间号码
  33. * @param string $StreamName 直播间号码
  34. * @return string
  35. * */
  36. public static function getliveStreamName($StreamName = '')
  37. {
  38. if ($StreamName) {
  39. if (preg_match('/[\x7f-\xff]/', $StreamName)) return self::setErrorInfo('直播间号码不能为中文');
  40. if (strlen($StreamName) < 6) return self::setErrorInfo('直播间号码不能少于6位');
  41. if (self::be(['stream_name' => $StreamName])) return self::setErrorInfo('直播间号码已存在');
  42. return $StreamName;
  43. } else {
  44. $num = mt_rand(10, 99999999);//生成随机数
  45. //开头不允许为0
  46. if (strpos((string)$num, chr(0)) === 0) return self::getliveStreamName();
  47. //不允许连续出现预设的数字
  48. foreach (self::$taboo as $val) {
  49. if (strstr((string)$num, $val)) return self::getliveStreamName();
  50. }
  51. if (strlen($num) > 6)
  52. $num = str_pad((string)$num, 8, 0, STR_PAD_RIGHT);//大于6位的填充到8位
  53. else
  54. $num = str_pad((string)$num, 6, 0, STR_PAD_RIGHT);//小于6位的填充到6位
  55. if (self::be(['stream_name' => $num])) return self::getliveStreamName();
  56. return $num;
  57. }
  58. }
  59. /**
  60. * 设置直播间直播状态
  61. * @param $StreamName
  62. * @return bool|false|int
  63. * @throws \think\db\exception\DataNotFoundException
  64. * @throws \think\db\exception\ModelNotFoundException
  65. * @throws \think\exception\DbException
  66. */
  67. public static function setLivePalyStatus($StreamName, $is_play, $action)
  68. {
  69. $liveInfo = self::where('stream_name', $StreamName)->find();
  70. if (!$liveInfo) return self::setErrorInfo('暂未查到直播间');
  71. live_log('log', ['title'=>'开始','liveInfo'=>$liveInfo->toArray(),'streamName'=>$StreamName,'is_play'=>$is_play]);
  72. if ($liveInfo->is_play == 1 && $action == 'publish') {
  73. return true;
  74. } else if ($liveInfo->is_play == 0 && $action == 'publish_done') {
  75. return true;
  76. }
  77. $liveInfo->is_play = $is_play;
  78. try {
  79. $aliyunLive = \Api\AliyunLive::instance([
  80. 'AccessKey' => SystemConfigService::get('accessKeyId'),
  81. 'AccessKeySecret' => SystemConfigService::get('accessKeySecret'),
  82. 'OssEndpoint' => SystemConfigService::get('aliyun_live_end_point'),
  83. 'OssBucket' => SystemConfigService::get('aliyun_live_oss_bucket'),
  84. 'appName' => SystemConfigService::get('aliyun_live_appName'),
  85. 'payKey' => SystemConfigService::get('aliyun_live_play_key'),
  86. 'key' => SystemConfigService::get('aliyun_live_push_key'),
  87. 'playLike' => SystemConfigService::get('aliyun_live_playLike'),
  88. 'rtmpLink' => SystemConfigService::get('aliyun_live_rtmpLink'),
  89. ]);
  90. if ($liveInfo->is_play) {
  91. //开启自动录制,进行手开启动录制直播间
  92. if ($liveInfo->is_recording) {
  93. $res = $aliyunLive->liveRecording($liveInfo->stream_name)->executeResponse();
  94. live_log('log', ['title'=>'直播录制开启','res'=>$res,'error'=>$aliyunLive->getErrorInfo()]);
  95. if ($res) $liveInfo->recording = 1;
  96. }
  97. //向所有在线用户广播直播地址
  98. $workerman = \think\Config::get('workerman.channel', []);
  99. Gateway::$registerAddress = $workerman['ip'] . ':' . $workerman['port'];
  100. if (Gateway::getClientIdCountByGroup($liveInfo->id)) {
  101. Gateway::sendToGroup($liveInfo->id, json_encode([
  102. 'type' => 'live_ing',
  103. 'pull_url' => $aliyunLive->getPullSteam($liveInfo->stream_name),
  104. ]));
  105. }
  106. } else {
  107. //开启自动录制,进行手动停止录制直播间
  108. if ($liveInfo->recording) {
  109. $res = $aliyunLive->liveRecording($liveInfo->stream_name, false)->executeResponse();
  110. live_log('log', ['title'=>'直播录制关闭','res'=>$res,'error'=>$aliyunLive->getErrorInfo()]);
  111. $liveInfo->recording = 0;
  112. }
  113. //向所有在线用户广播直播地址
  114. $workerman = \think\Config::get('workerman.channel', []);
  115. Gateway::$registerAddress = $workerman['ip'] . ':' . $workerman['port'];
  116. if (Gateway::getClientIdCountByGroup($liveInfo->id)) {
  117. Gateway::sendToGroup($liveInfo->id, json_encode([
  118. 'type' => 'live_end',
  119. 'pull_url' => false,
  120. ]));
  121. }
  122. }
  123. } catch (\Exception $e) {
  124. live_log('error', ['code' => $e->getCode(), 'line' => $e->getLine(), 'msg' => $e->getMessage()]);
  125. if ($liveInfo->recording) $liveInfo->recording = 0;
  126. self::setErrorInfo($e->getMessage());
  127. }
  128. return $liveInfo->save();
  129. }
  130. /**
  131. * 设置直播查询条件
  132. * @param $where
  133. * @param null $model
  134. * @param string $alias
  135. * @return $this
  136. */
  137. public static function setLiveWhere($where, $model = null, $alias = '')
  138. {
  139. $model = is_null($model) ? new self() : $model;
  140. if ($alias) {
  141. $model = $model->alias($alias);
  142. $alias .= '.';
  143. }
  144. if ($where['special_id']) $model = $model->where("{$alias}special_id", $where['special_id']);
  145. if (isset($where['admin_id']) && $where['admin_id']) $model = $model->where("S.admin_id", $where['admin_id']);
  146. if ($where['stream_name']) $model = $model->where("{$alias}stream_name", $where['stream_name']);
  147. if ($where['start_time'] && $where['end_time']) $model = $model->where("{$alias}add_time", 'between', [strtotime($where['start_time']), strtotime($where['end_time'])]);
  148. return $model->where("{$alias}is_del", 0);
  149. }
  150. /**
  151. * 查询直播间列表
  152. * @param $where
  153. * @return array
  154. * @throws \think\Exception
  155. */
  156. public static function getLiveList($where)
  157. {
  158. $data = self::setLiveWhere($where,null,'L')
  159. ->field('L.*, S.admin_id as admin_id,S.pay_type,S.member_pay_type')->join('__SPECIAL__ S', 'L.special_id=S.id', 'LEFT')->order('L.sort desc,L.add_time desc')->page((int)$where['page'], (int)$where['limit'])->select();
  160. $data = count($data) ? $data->toArray() : [];
  161. foreach ($data as &$item) {
  162. $item['add_time'] = date('Y-m-d H:i:s', $item['add_time']);
  163. $item['studio_pwd'] = $item['studio_pwd'] ?: '';
  164. $buy_user_num=StoreOrder::where(['paid' => 1, 'cart_id' => $item['special_id']])->count('id');
  165. if($item['pay_type']==1 && $item['member_pay_type']==1){
  166. $item['buy_user_num'] = $buy_user_num;
  167. }elseif($item['pay_type']==1 && $item['member_pay_type']==0){
  168. $userCount =User::where('is_h5user',0)->where('level',1)->count("uid");
  169. $item['buy_user_num'] =bcadd($buy_user_num,$userCount,0);
  170. }else{
  171. $item['buy_user_num'] =User::where('is_h5user',0)->count("uid");
  172. }
  173. $item['online_user_num'] =LiveUser::where(['is_online'=>1,'live_id'=>$item['id']])->count();
  174. }
  175. $count = self::setLiveWhere($where, null, 'L')->join('__SPECIAL__ S', 'L.special_id=S.id', 'LEFT')->count();
  176. return compact('data', 'count');
  177. }
  178. }