LiveingController.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <?php
  2. // +—————————————————————————————————————————————————————————————————————
  3. // | Created by Yunbao
  4. // +—————————————————————————————————————————————————————————————————————
  5. // | Copyright (c) 2013~2022 http://www.yunbaokj.com All rights reserved.
  6. // +—————————————————————————————————————————————————————————————————————
  7. // | Author: https://gitee.com/yunbaokeji
  8. // +—————————————————————————————————————————————————————————————————————
  9. // | Date: 2022-02-17
  10. // +—————————————————————————————————————————————————————————————————————
  11. /**
  12. * 直播列表
  13. */
  14. namespace app\admin\controller;
  15. use cmf\controller\AdminBaseController;
  16. use think\Db;
  17. // 根据腾讯云sdk请求 创建直播拉流
  18. use TencentCloud\Live\V20180801\Models\CreateLivePullStreamTaskRequest;
  19. use TencentCloud\Live\V20180801\Models\DeleteLivePullStreamTaskRequest;
  20. use TencentCloud\Common\Exception\TencentCloudSDKException;
  21. use TencentCloud\Common\Credential;
  22. use TencentCloud\Common\Profile\ClientProfile;
  23. use TencentCloud\Common\Profile\HttpProfile;
  24. use TencentCloud\Live\V20180801\LiveClient;
  25. use think\Exception;
  26. use think\exception\PDOException;
  27. class LiveingController extends AdminbaseController {
  28. protected function getLiveClass(){
  29. $liveclass=Db::name("live_class")->order('list_order asc, id desc')->column('id,name');
  30. return $liveclass;
  31. }
  32. protected function getTypes($k=''){
  33. $type=[
  34. '0'=>'普通房间',
  35. '1'=>'密码房间',
  36. '2'=>'门票房间',
  37. '3'=>'计时房间',
  38. ];
  39. if($k==''){
  40. return $type;
  41. }
  42. return $type[$k];
  43. }
  44. public function index(){
  45. $data = $this->request->param();
  46. $map=[];
  47. $map[]=['islive','=',1];
  48. $start_time=isset($data['start_time']) ? $data['start_time']: '';
  49. $end_time=isset($data['end_time']) ? $data['end_time']: '';
  50. if($start_time!=""){
  51. $map[]=['starttime','>=',strtotime($start_time)];
  52. }
  53. if($end_time!=""){
  54. $map[]=['starttime','<=',strtotime($end_time) + 60*60*24];
  55. }
  56. $uid=isset($data['uid']) ? $data['uid']: '';
  57. if($uid!=''){
  58. $lianguid=getLianguser($uid);
  59. if($lianguid){
  60. $map[]=['uid',['=',$uid],['in',$lianguid],'or'];
  61. }else{
  62. $map[]=['uid','=',$uid];
  63. }
  64. }
  65. $this->configpri=getConfigPri();
  66. $lists = Db::name("live")
  67. ->where($map)
  68. ->order("starttime DESC")
  69. ->paginate(20);
  70. $lists->each(function($v,$k){
  71. $v['userinfo']=getUserInfo($v['uid']);
  72. $where=[];
  73. $where['action']=1;
  74. $where['touid']=$v['uid'];
  75. $where['showid']=$v['showid'];
  76. /* 本场总收益 */
  77. $totalcoin=Db::name("user_coinrecord")->where($where)->sum('totalcoin');
  78. if(!$totalcoin){
  79. $totalcoin=0;
  80. }
  81. /* 送礼物总人数 */
  82. $total_nums=Db::name("user_coinrecord")->where($where)->group("uid")->count();
  83. if(!$total_nums){
  84. $total_nums=0;
  85. }
  86. /* 人均 */
  87. $total_average=0;
  88. if($totalcoin && $total_nums){
  89. $total_average=round($totalcoin/$total_nums,2);
  90. }
  91. /* 人数 */
  92. $nums=zSize('user_'.$v['stream']);
  93. $v['totalcoin']=$totalcoin;
  94. $v['total_nums']=$total_nums;
  95. $v['total_average']=$total_average;
  96. $v['nums']=$nums;
  97. if($v['isvideo']==0 && $this->configpri['cdn_switch']!=5){
  98. $v['pull']=PrivateKeyA('rtmp',$v['stream'],0);
  99. }
  100. return $v;
  101. });
  102. $lists->appends($data);
  103. $page = $lists->render();
  104. $liveclass=$this->getLiveClass();
  105. $liveclass[0]='默认分类';
  106. $this->assign('lists', $lists);
  107. $this->assign("page", $page);
  108. $this->assign("liveclass", $liveclass);
  109. $this->assign("type", $this->getTypes());
  110. return $this->fetch();
  111. }
  112. public function getLivePushUrl(){
  113. $uid = $_POST['uid'] ?? ''; // 从 POST 请求中获取 uid 值
  114. if (empty($uid)) {
  115. echo "请输入UID";
  116. } elseif (!is_numeric($uid)) {
  117. echo "UID必须是数字";
  118. } else {
  119. $tx_push = cmf_get_option('configpri')['tx_push'];
  120. $push_url = 'rtmp://' . $tx_push.'/live/'.$uid;
  121. $pull_key = cmf_get_option('configpri')['tx_play_key'];
  122. require CMF_ROOT . 'vendor/tencentcloud/vendor/autoload.php';
  123. try {
  124. // 为了保护密钥安全,建议将密钥设置在环境变量中或者配置文件中。
  125. // 硬编码密钥到代码中有可能随代码泄露而暴露,有安全隐患,并不推荐。
  126. // $cred = new Credential("SecretId", "SecretKey");
  127. $cred = new Credential("AKID575vicM9rU6iBiWJNi09HF8xhMxOk4Od",
  128. "MiDkHwgOFpMpGf2KXcZIo9MYY5qnmhU5");
  129. // 实例化一个http选项,可选的,没有特殊需求可以跳过
  130. $httpProfile = new HttpProfile();
  131. $httpProfile->setEndpoint( "live.tencentcloudapi.com" );
  132. // 实例化一个client选项,可选的,没有特殊需求可以跳过
  133. $clientProfile = new ClientProfile();
  134. $clientProfile->setHttpProfile( $httpProfile );
  135. // 实例化要请求产品的client对象,clientProfile是可选的
  136. $client = new LiveClient( $cred, "ap-bangkok", $clientProfile );
  137. // 实例化一个请求对象,每个接口都会对应一个request对象
  138. $req = new CreateLivePullStreamTaskRequest();
  139. // https://umotool.com 推流域名
  140. $SourceUrls = ['https://umotool.com/live/'.$uid.'.flv'];
  141. $timestamp = time();
  142. //播放链接限制10分钟 60*10 一天 60*60*24
  143. $end_timestamp = time() + 60*60*24;
  144. $txTime = strtoupper(base_convert($end_timestamp, 10, 16));
  145. $txSecret = md5( $pull_key . $uid . $txTime );
  146. $params = array(
  147. "SourceType" => "PullLivePushLive",
  148. "SourceUrls" => $SourceUrls,
  149. "DomainName" => 'https://umotool.com',
  150. "PushArgs" => 'txSecret='.$txSecret.'&txTime='.$txTime,
  151. "AppName" => 'live',
  152. "StreamName" => $uid,
  153. "StartTime" => gmdate("Y-m-d\TH:i:s\Z", $timestamp),
  154. "EndTime" => gmdate("Y-m-d\TH:i:s\Z", $end_timestamp),
  155. "Operator" => 'tom001',
  156. );
  157. // print_r($params);die;
  158. $req->fromJsonString( json_encode( $params ) );
  159. // 返回的resp是一个CreateLivePullStreamTaskResponse的实例,与请求对象对应
  160. $resp = $client->CreateLivePullStreamTask( $req );
  161. // 推流地址、播流地址、taskId
  162. $data['push'] = 'rtmp://push.umotool.com/live/'. $uid . '?' .$params['PushArgs'];
  163. $data['pull'] = 'https://umotool.com/live/'.$uid.'.flv?' .$params['PushArgs'];
  164. $data['TaskId'] = $resp->TaskId;
  165. echo json_encode( $data , JSON_UNESCAPED_UNICODE );
  166. }
  167. catch(TencentCloudSDKException $e) {
  168. echo $e;
  169. }
  170. }
  171. }
  172. public function xiabo()
  173. {
  174. $uid = $_POST['uid'];
  175. $TaskId = $_POST['TaskId'];
  176. if (empty($uid) || empty($TaskId)) {
  177. echo "请输入 TaskId";
  178. } elseif (!is_numeric($uid) || !is_numeric($TaskId)) {
  179. echo "TaskId 必须是数字";
  180. } else {
  181. try {
  182. // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
  183. // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。密钥可前往官网控制台 https://console.tencentcloud.com/capi 进行获取
  184. $cred = new Credential("AKID575vicM9rU6iBiWJNi09HF8xhMxOk4Od",
  185. "MiDkHwgOFpMpGf2KXcZIo9MYY5qnmhU5");
  186. // 实例化一个http选项,可选的,没有特殊需求可以跳过
  187. $httpProfile = new HttpProfile();
  188. $httpProfile->setEndpoint( "live.tencentcloudapi.com" );
  189. // 实例化一个client选项,可选的,没有特殊需求可以跳过
  190. $clientProfile = new ClientProfile();
  191. $clientProfile->setHttpProfile( $httpProfile );
  192. // 实例化要请求产品的client对象,clientProfile是可选的
  193. $client = new LiveClient( $cred, "ap-bangkok", $clientProfile );
  194. // 实例化一个请求对象,每个接口都会对应一个request对象
  195. $req = new DeleteLivePullStreamTaskRequest();
  196. $params = array(
  197. "TaskId" => $TaskId,
  198. "Operator" => "tom001"
  199. );
  200. $req->fromJsonString( json_encode( $params ) );
  201. // 返回的resp是一个DeleteLivePullStreamTaskResponse的实例,与请求对象对应
  202. $resp = $client->DeleteLivePullStreamTask( $req );
  203. // 输出json格式的字符串回包
  204. $json = $resp->toJsonString();
  205. $data['uid'] = $uid;
  206. $data['TaskId'] = '已下播-'.$TaskId;
  207. $rs = DB::name('live')->update($data);
  208. // return $json;
  209. return json_decode( $json, 1 );
  210. } catch ( TencentCloudSDKException $e ) {
  211. return [ 'ode' => $e->getCode(), 'msg' => $e->getMessage() ];
  212. } catch ( PDOException $e ) {
  213. return [ 'ode' => $e->getCode(), 'msg' => $e->getMessage() ];
  214. }catch ( Exception $e ) {
  215. return [ 'ode' => $e->getCode(), 'msg' => $e->getMessage() ];
  216. }
  217. }
  218. }
  219. public function del(){
  220. $uid = $this->request->param('uid', 0, 'intval');
  221. $rs = DB::name('live')->where("uid={$uid}")->delete();
  222. if(!$rs){
  223. $this->error("删除失败!");
  224. }
  225. $this->success("删除成功!",url("liveing/index"));
  226. }
  227. public function add(){
  228. $this->assign("liveclass", $this->getLiveClass());
  229. $this->assign("type", $this->getTypes());
  230. return $this->fetch();
  231. }
  232. public function addPost(){
  233. if ($this->request->isPost()) {
  234. $data = $this->request->param();
  235. $nowtime=time();
  236. $uid=$data['uid'];
  237. $userinfo=DB::name('user')->field("ishot")->where(["id"=>$uid,"user_type"=>2])->find();
  238. if(!$userinfo){
  239. $this->error('用户不存在');
  240. }
  241. $liveinfo=DB::name('live')->field('uid,islive')->where(["uid"=>$uid])->find();
  242. if($liveinfo['islive']==1){
  243. $this->error('该用户正在直播');
  244. }
  245. $TaskId=$data['TaskId'];
  246. $pull=urldecode($data['pull']);
  247. $push=urldecode($data['push']);
  248. $type=$data['type'];
  249. $type_val=$data['type_val'];
  250. $anyway=$data['anyway'];
  251. $liveclassid=$data['liveclassid'];
  252. $stream=$uid.'_'.$nowtime;
  253. $title='';
  254. $data2=array(
  255. "uid"=>$uid,
  256. "showid"=>$nowtime,
  257. "starttime"=>$nowtime,
  258. "title"=>$title,
  259. "province"=>'',
  260. "city"=>'好像在火星',
  261. "stream"=>$stream,
  262. "thumb"=>'',
  263. "TaskId"=>$TaskId,
  264. "pull"=>$pull,
  265. "push"=>$push,
  266. "lng"=>'',
  267. "lat"=>'',
  268. "type"=>$type,
  269. "type_val"=>$type_val,
  270. "isvideo"=>1,
  271. "islive"=>1,
  272. "anyway"=>$anyway,
  273. "liveclassid"=>$liveclassid,
  274. );
  275. if($liveinfo){
  276. $rs = DB::name('live')->update($data2);
  277. }else{
  278. $rs = DB::name('live')->insertGetId($data2);
  279. }
  280. if($rs===false){
  281. $this->error("添加失败!");
  282. }
  283. $this->success("添加成功!");
  284. }
  285. }
  286. public function edit(){
  287. $uid = $this->request->param('uid', 0, 'intval');
  288. $data=Db::name('live')
  289. ->where("uid={$uid}")
  290. ->find();
  291. if(!$data){
  292. $this->error("信息错误");
  293. }
  294. $this->assign('data', $data);
  295. $this->assign("liveclass", $this->getLiveClass());
  296. $this->assign("type", $this->getTypes());
  297. return $this->fetch();
  298. }
  299. public function editPost(){
  300. if ($this->request->isPost()) {
  301. $data = $this->request->param();
  302. $data['pull']=urldecode($data['pull']);
  303. $data['push']=urldecode($data['push']);
  304. $rs = DB::name('live')->update($data);
  305. if($rs===false){
  306. $this->error("修改失败!");
  307. }
  308. $this->success("修改成功!");
  309. }
  310. }
  311. }