Live.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  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. class Api_Live extends PhalApi_Api {
  15. public function getRules() {
  16. return array(
  17. 'getSDK' => array(
  18. 'uid' => array('name' => 'uid', 'type' => 'int', 'desc' => '用户ID'),
  19. ),
  20. 'createRoom' => array(
  21. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  22. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  23. 'title' => array('name' => 'title', 'type' => 'string','default'=>'', 'desc' => '直播标题 url编码'),
  24. 'province' => array('name' => 'province', 'type' => 'string', 'default'=>'', 'desc' => '省份'),
  25. 'city' => array('name' => 'city', 'type' => 'string', 'default'=>'', 'desc' => '城市'),
  26. 'lng' => array('name' => 'lng', 'type' => 'string', 'default'=>'0', 'desc' => '经度值'),
  27. 'lat' => array('name' => 'lat', 'type' => 'string', 'default'=>'0', 'desc' => '纬度值'),
  28. 'type' => array('name' => 'type', 'type' => 'int', 'default'=>'0', 'desc' => '直播房间类型,0是普通房间,1是私密房间,2是收费房间,3是计时房间'),
  29. 'type_val' => array('name' => 'type_val', 'type' => 'string', 'default'=>'', 'desc' => '类型值'),
  30. 'anyway' => array('name' => 'anyway', 'type' => 'int', 'default'=>'0', 'desc' => '直播类型 1 PC, 0 app'),
  31. 'liveclassid' => array('name' => 'liveclassid', 'type' => 'int', 'default'=>'0', 'desc' => '直播分类ID'),
  32. 'deviceinfo' => array('name' => 'deviceinfo', 'type' => 'string', 'default'=>'', 'desc' => '设备信息'),
  33. 'thumb' => array('name' => 'thumb', 'type' => 'string', 'desc' => '开播封面'),
  34. ),
  35. 'changeLive' => array(
  36. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  37. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  38. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  39. 'status' => array('name' => 'status', 'type' => 'int', 'require' => true, 'desc' => '直播状态 0关闭 1直播'),
  40. ),
  41. 'stopRoom' => array(
  42. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  43. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  44. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  45. 'type' => array('name' => 'type', 'type' => 'int', 'default'=>'0', 'desc' => '类型'),
  46. 'source' => array('name' => 'source', 'type' => 'string', 'desc' => '访问来源 socekt:断联socket,app传值空'),
  47. 'time' => array('name' => 'time', 'type' => 'string', 'desc' => '当前时间戳'),
  48. 'sign' => array('name' => 'sign', 'type' => 'string', 'desc' => '签名'),
  49. ),
  50. 'stopInfo' => array(
  51. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  52. ),
  53. 'checkLive' => array(
  54. 'uid' => array('name' => 'uid', 'type' => 'int', 'require' => true, 'desc' => '用户ID'),
  55. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  56. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  57. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  58. ),
  59. 'roomCharge' => array(
  60. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  61. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  62. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  63. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  64. ),
  65. 'timeCharge' => array(
  66. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  67. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  68. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  69. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  70. ),
  71. 'enterRoom' => array(
  72. 'uid' => array('name' => 'uid', 'type' => 'string', 'require' => true, 'desc' => '用户ID'),
  73. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  74. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  75. // 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  76. 'city' => array('name' => 'city', 'type' => 'string','default'=>'', 'desc' => '城市'),
  77. 'mobileid' => array('name' => 'mobileid', 'type' => 'string','default'=>'', 'desc' => '实际唯一识别码'),
  78. 'usernicename' => array('name' => 'usernicename', 'type' => 'string','default'=>'', 'desc' => '用户名'),
  79. ),
  80. 'getUserLists' => array(
  81. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  82. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  83. 'p' => array('name' => 'p', 'type' => 'int', 'min' => 1, 'default'=>1,'desc' => '页数'),
  84. ),
  85. 'getPop' => array(
  86. 'uid' => array('name' => 'uid', 'type' => 'int', 'require' => true, 'desc' => '用户ID'),
  87. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  88. 'touid' => array('name' => 'touid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '对方ID'),
  89. ),
  90. 'getGiftList' => array(
  91. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  92. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  93. ),
  94. 'sendGift' => array(
  95. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  96. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  97. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  98. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  99. 'giftid' => array('name' => 'giftid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '礼物ID'),
  100. 'giftcount' => array('name' => 'giftcount', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '礼物数量'),
  101. 'touids' => array('name' => 'touids', 'type' => 'string', 'require' => true, 'desc' => '接收送礼物的麦上用户组'),
  102. ),
  103. 'sendBarrage' => array(
  104. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '用户ID'),
  105. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'desc' => '用户token'),
  106. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  107. 'stream' => array('name' => 'stream', 'type' => 'string', 'require' => true, 'desc' => '流名'),
  108. 'content' => array('name' => 'content', 'type' => 'string', 'min' => 1, 'require' => true, 'desc' => '弹幕内容'),
  109. ),
  110. 'getVotes' => array(
  111. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '主播ID'),
  112. ),
  113. 'getCoin' => array(
  114. 'uid' => array('name' => 'uid', 'type' => 'int', 'min' => 1, 'require' => true, 'desc' => '会员ID'),
  115. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'min' => 1, 'desc' => '会员token'),
  116. ),
  117. 'checkLiveing' => array(
  118. 'uid' => array('name' => 'uid', 'type' => 'int','desc' => '会员ID'),
  119. 'token' => array('name' => 'token', 'type' => 'string', 'require' => true, 'min' => 1, 'desc' => '会员token'),
  120. 'stream' => array('name' => 'stream', 'type' => 'string','desc' => '流名'),
  121. ),
  122. 'getLiveInfo' => array(
  123. 'liveuid' => array('name' => 'liveuid', 'type' => 'int', 'desc' => '主播ID'),
  124. ),
  125. );
  126. }
  127. /**
  128. * 获取SDK
  129. * @desc 用于获取SDK类型
  130. * @return int code 操作码,0表示成功
  131. * @return array info
  132. * @return string info[0].live_sdk SDK类型,0金山SDK 1腾讯SDK
  133. * @return object info[0].android 安卓CDN配置
  134. * @return object info[0].ios IOS CDN配置
  135. * @return string info[0].isshop 是否有店铺,0否1是
  136. * @return string msg 提示信息
  137. */
  138. public function getSDK() {
  139. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  140. $uid=checkNull($this->uid);
  141. $cdnset=include API_ROOT.'/../PhalApi/Config/cdnset.php';
  142. $rs['info'][0]=$cdnset;
  143. return $rs;
  144. }
  145. /**
  146. * 创建开播
  147. * @desc 用于用户开播生成记录
  148. * @return int code 操作码,0表示成功
  149. * @return array info
  150. * @return string info[0].userlist_time 用户列表请求间隔
  151. * @return string info[0].barrage_fee 弹幕价格
  152. * @return string info[0].votestotal 主播映票
  153. * @return string info[0].stream 流名
  154. * @return string info[0].push 推流地址
  155. * @return string info[0].pull 播流地址
  156. * @return string info[0].chatserver socket地址
  157. * @return array info[0].game_switch 游戏开关
  158. * @return string info[0].game_switch[][0] 开启的游戏类型
  159. * @return string info[0].game_bankerid 庄家ID
  160. * @return string info[0].game_banker_name 庄家昵称
  161. * @return string info[0].game_banker_avatar 庄家头像
  162. * @return string info[0].game_banker_coin 庄家余额
  163. * @return string info[0].game_banker_limit 上庄限额
  164. * @return object info[0].liang 用户靓号信息
  165. * @return string info[0].liang.name 号码,0表示无靓号
  166. * @return object info[0].vip 用户VIP信息
  167. * @return string info[0].vip.type VIP类型,0表示无VIP,1表示有VIP
  168. * @return string info[0].guard_nums 守护数量
  169. * @return string info[0].thumb 直播封面
  170. * @return string msg 提示信息
  171. */
  172. public function createRoom() {
  173. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  174. $uid = checkNull($this->uid);
  175. $token=checkNull($this->token);
  176. $configpub=getConfigPub();
  177. if($configpub['maintain_switch']==1){
  178. $rs['code']=1002;
  179. $rs['msg']=$configpub['maintain_tips'];
  180. return $rs;
  181. }
  182. $checkToken=checkToken($uid,$token);
  183. if($checkToken==700){
  184. $rs['code'] = $checkToken;
  185. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  186. return $rs;
  187. }
  188. $configpri=getConfigPri();
  189. if($configpri['auth_islimit']==1){
  190. $isauth=isAuth($uid);
  191. if(!$isauth){
  192. $rs['code']=1002;
  193. $rs['msg']='请先进行身份认证或等待审核';
  194. return $rs;
  195. }
  196. }
  197. $userinfo=getUserInfo($uid);
  198. if($configpri['level_islimit']==1){
  199. if( $userinfo['level'] < $configpri['level_limit'] ){
  200. $rs['code']=1003;
  201. $rs['msg']='等级小于'.$configpri['level_limit'].'级,不能直播';
  202. return $rs;
  203. }
  204. }
  205. $nowtime=time();
  206. $showid=$nowtime;
  207. $starttime=$nowtime;
  208. $title=checkNull($this->title);
  209. $province=checkNull($this->province);
  210. $city=checkNull($this->city);
  211. $lng=checkNull($this->lng);
  212. $lat=checkNull($this->lat);
  213. $type=checkNull($this->type);
  214. $type_val=checkNull($this->type_val);
  215. $anyway=checkNull($this->anyway);
  216. $liveclassid=checkNull($this->liveclassid);
  217. $deviceinfo=checkNull($this->deviceinfo);
  218. $thumb_str=checkNull($this->thumb);
  219. $sensitivewords=sensitiveField($title);
  220. if($sensitivewords==1001){
  221. $rs['code'] = 10011;
  222. $rs['msg'] = '输入非法,请重新输入';
  223. return $rs;
  224. }
  225. if( $type==1 && $type_val=='' ){
  226. $rs['code']=1002;
  227. $rs['msg']='密码不能为空';
  228. return $rs;
  229. }else if($type > 1 && $type_val<=0){
  230. $rs['code']=1002;
  231. $rs['msg']='价格不能小于等于0';
  232. return $rs;
  233. }
  234. $stream=$uid.'_'.$nowtime;
  235. $push=PrivateKeyA('rtmp',$stream,1);
  236. $pull=PrivateKeyA('rtmp',$stream,0);
  237. if(!$city){
  238. $city='好像在火星';
  239. }
  240. if(!$lng && $lng!=0){
  241. $lng='';
  242. }
  243. if(!$lat && $lat!=0){
  244. $lat='';
  245. }
  246. //APP原生上传后请求接口保存start
  247. $thumb="";
  248. if($thumb_str){
  249. $cloudtype=$configpri['cloudtype'];
  250. if($cloudtype==1){ //七牛云存储
  251. $thumb= $thumb_str.'?imageView2/2/w/600/h/600';
  252. }else{
  253. $thumb=$thumb_str;
  254. }
  255. }
  256. $dataroom=array(
  257. "uid"=>$uid,
  258. "showid"=>$showid,
  259. "starttime"=>$starttime,
  260. "title"=>$title,
  261. "province"=>$province,
  262. "city"=>$city,
  263. "stream"=>$stream,
  264. "thumb"=>$thumb,
  265. "pull"=>$pull,
  266. "lng"=>$lng,
  267. "lat"=>$lat,
  268. "type"=>$type,
  269. "type_val"=>$type_val,
  270. "isvideo"=>0,
  271. "islive"=>0,
  272. "anyway"=>$anyway,
  273. "liveclassid"=>$liveclassid,
  274. "deviceinfo"=>$deviceinfo,
  275. "hotvotes"=>0,
  276. );
  277. $domain = new Domain_Live();
  278. $result = $domain->createRoom($uid,$dataroom);
  279. if($result===false){
  280. $rs['code'] = 1011;
  281. $rs['msg'] = '开播失败,请重试';
  282. return $rs;
  283. }
  284. $userinfo['city']=$city;
  285. $userinfo['usertype']=50;
  286. $userinfo['sign']='0';
  287. DI()->redis -> set($token,json_encode($userinfo));
  288. $votestotal=$domain->getVotes($uid);
  289. $info['userlist_time']=$configpri['userlist_time'];
  290. $info['barrage_fee']=$configpri['barrage_fee'];
  291. $info['chatserver']=$configpri['chatserver'];
  292. $info['votestotal']=$votestotal;
  293. $info['stream']=$stream;
  294. $info['push']=$push;
  295. $info['pull']=$pull;
  296. // 腾讯APPID
  297. $info['tx_appid']=$configpri['tx_appid'];
  298. // 敏感词集合
  299. $dirtyarr=array();
  300. if($configpri['sensitive_words']){
  301. $dirtyarr=explode(',',$configpri['sensitive_words']);
  302. }
  303. $info['sensitive_words']=$dirtyarr;
  304. //返回直播封面
  305. if($thumb){
  306. $info['thumb']=get_upload_path($thumb);
  307. }else{
  308. $info['thumb']=$userinfo['avatar_thumb'];
  309. }
  310. $rs['info'][0] = $info;
  311. return $rs;
  312. }
  313. /**
  314. * 修改直播状态
  315. * @desc 用于主播修改直播状态
  316. * @return int code 操作码,0表示成功
  317. * @return array info
  318. * @return string info[0].msg 成功提示信息
  319. * @return string msg 提示信息
  320. */
  321. public function changeLive() {
  322. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  323. $uid = checkNull($this->uid);
  324. $token=checkNull($this->token);
  325. $stream=checkNull($this->stream);
  326. $status=checkNull($this->status);
  327. $checkToken=checkToken($uid,$token);
  328. if($checkToken==700){
  329. $rs['code'] = $checkToken;
  330. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  331. return $rs;
  332. }
  333. $domain = new Domain_Live();
  334. $info=$domain->changeLive($uid,$stream,$status);
  335. $rs['info'][0]['msg']='成功';
  336. return $rs;
  337. }
  338. /**
  339. * 关闭直播
  340. * @desc 用于用户结束直播
  341. * @return int code 操作码,0表示成功
  342. * @return array info
  343. * @return string info[0].msg 成功提示信息
  344. * @return string msg 提示信息
  345. */
  346. public function stopRoom() {
  347. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  348. $uid = checkNull($this->uid);
  349. $token=checkNull($this->token);
  350. $stream=checkNull($this->stream);
  351. $type=checkNull($this->type);
  352. $source=checkNull($this->source);
  353. $time=checkNull($this->time);
  354. $sign=checkNull($this->sign);
  355. if(!$source){ //非socket来源,app访问
  356. if(!$time){
  357. $rs['code'] = 1001;
  358. $rs['msg'] = '参数错误,请重试';
  359. return $rs;
  360. }
  361. $now=time();
  362. if($now-$time>300){
  363. $rs['code']=1001;
  364. $rs['msg']='参数错误';
  365. return $rs;
  366. }
  367. if(!$sign){
  368. $rs['code']=1001;
  369. $rs['msg']="参数错误,请重试";
  370. return $rs;
  371. }
  372. $checkdata=array(
  373. 'uid'=>$uid,
  374. 'token'=>$token,
  375. 'time'=>$time,
  376. 'stream'=>$stream,
  377. );
  378. $issign=checkSign($checkdata,$sign);
  379. if(!$issign){
  380. $rs['code']=1001;
  381. $rs['msg']='签名错误';
  382. return $rs;
  383. }
  384. }
  385. $key='stopRoom_'.$stream;
  386. $isexist=getcaches($key);
  387. if(!$isexist ){
  388. $domain = new Domain_Live();
  389. $checkToken=checkToken($uid,$token);
  390. setcaches($key,'1',10);
  391. if($checkToken==700){
  392. $domain->stopRoom($uid,$stream);
  393. $rs['code'] = $checkToken;
  394. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  395. return $rs;
  396. }
  397. $info=$domain->stopRoom($uid,$stream);
  398. }
  399. $rs['info'][0]['msg']='关播成功';
  400. return $rs;
  401. }
  402. /**
  403. * 直播结束信息
  404. * @desc 用于直播结束页面信息展示
  405. * @return int code 操作码,0表示成功
  406. * @return array info
  407. * @return string info[0].nums 人数
  408. * @return string info[0].length 时长
  409. * @return string info[0].votes 映票数
  410. * @return string msg 提示信息
  411. */
  412. public function stopInfo() {
  413. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  414. $stream=checkNull($this->stream);
  415. $domain = new Domain_Live();
  416. $info=$domain->stopInfo($stream);
  417. $rs['info'][0]=$info;
  418. return $rs;
  419. }
  420. /**
  421. * 检查直播状态
  422. * @desc 用于用户进房间时检查直播状态
  423. * @return int code 操作码,0表示成功
  424. * @return array info
  425. * @return string info[0].type 房间类型
  426. * @return string info[0].type_val 收费房间价格,默认0
  427. * @return string info[0].type_msg 提示信息
  428. * @return string info[0].live_type 房间类型 0 视频直播 1 语音聊天室
  429. * @return string msg 提示信息
  430. */
  431. public function checkLive() {
  432. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  433. $uid=checkNull($this->uid);
  434. $token=checkNull($this->token);
  435. $liveuid=checkNull($this->liveuid);
  436. $stream=checkNull($this->stream);
  437. $configpub=getConfigPub();
  438. if($configpub['maintain_switch']==1){
  439. $rs['code']=1002;
  440. $rs['msg']=$configpub['maintain_tips'];
  441. return $rs;
  442. }
  443. if($uid>0){
  444. $checkToken=checkToken($uid,$token);
  445. if($checkToken==700){
  446. $rs['code'] = $checkToken;
  447. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  448. return $rs;
  449. }
  450. }
  451. if($uid==$liveuid){
  452. $rs['code'] = 1011;
  453. $rs['msg'] = '不能进入自己的直播间';
  454. return $rs;
  455. }
  456. $domain = new Domain_Live();
  457. $info=$domain->checkLive($uid,$liveuid,$stream);
  458. if($info==1005){
  459. $rs['code'] = 1005;
  460. $rs['msg'] = '直播已结束';
  461. return $rs;
  462. }else if($info==1007){
  463. $rs['code'] = 1007;
  464. $rs['msg'] = '超管不能进入1v1房间';
  465. return $rs;
  466. }else if($info==1008){
  467. $rs['code'] = 1004;
  468. $rs['msg'] = '您已被踢出房间';
  469. return $rs;
  470. }
  471. $rs['info'][0]=$info;
  472. return $rs;
  473. }
  474. /**
  475. * 房间扣费
  476. * @desc 用于房间扣费
  477. * @return int code 操作码,0表示成功
  478. * @return array info
  479. * @return string info[0].coin 用户余额
  480. * @return string msg 提示信息
  481. */
  482. public function roomCharge() {
  483. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  484. $uid=checkNull($this->uid);
  485. $token=checkNull($this->token);
  486. $liveuid=checkNull($this->liveuid);
  487. $stream=checkNull($this->stream);
  488. $checkToken=checkToken($uid,$token);
  489. if($checkToken==700){
  490. $rs['code'] = $checkToken;
  491. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  492. return $rs;
  493. }
  494. $domain = new Domain_Live();
  495. $info=$domain->roomCharge($uid,$liveuid,$stream);
  496. if($info==1005){
  497. $rs['code'] = 1005;
  498. $rs['msg'] = '直播已结束';
  499. return $rs;
  500. }else if($info==1006){
  501. $rs['code'] = 1006;
  502. $rs['msg'] = '该房间非扣费房间';
  503. return $rs;
  504. }else if($info==1007){
  505. $rs['code'] = 1007;
  506. $rs['msg'] = '房间费用有误';
  507. return $rs;
  508. }else if($info==1008){
  509. $rs['code'] = 1008;
  510. $rs['msg'] = '余额不足';
  511. return $rs;
  512. }
  513. $rs['info'][0]['coin']=$info['coin'];
  514. return $rs;
  515. }
  516. /**
  517. * 房间计时扣费
  518. * @desc 用于房间计时扣费
  519. * @return int code 操作码,0表示成功
  520. * @return array info
  521. * @return string info[0].coin 用户余额
  522. * @return string msg 提示信息
  523. */
  524. public function timeCharge() {
  525. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  526. $uid=checkNull($this->uid);
  527. $token=checkNull($this->token);
  528. $liveuid=checkNull($this->liveuid);
  529. $stream=checkNull($this->stream);
  530. $checkToken=checkToken($uid,$token);
  531. if($checkToken==700){
  532. $rs['code'] = $checkToken;
  533. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  534. return $rs;
  535. }
  536. $domain = new Domain_Live();
  537. $key='timeCharge_'.$stream.'_'.$uid;
  538. $cache=getcaches($key);
  539. if($cache){
  540. $coin=$domain->getUserCoin($uid);
  541. $rs['info'][0]['coin']=$coin['coin'];
  542. return $rs;
  543. }
  544. $info=$domain->roomCharge($uid,$liveuid,$stream);
  545. if($info==1005){
  546. $rs['code'] = 1005;
  547. $rs['msg'] = '直播已结束';
  548. return $rs;
  549. }else if($info==1006){
  550. $rs['code'] = 1006;
  551. $rs['msg'] = '该房间非扣费房间';
  552. return $rs;
  553. }else if($info==1007){
  554. $rs['code'] = 1007;
  555. $rs['msg'] = '房间费用有误';
  556. return $rs;
  557. }else if($info==1008){
  558. $rs['code'] = 1008;
  559. $rs['msg'] = '余额不足';
  560. return $rs;
  561. }
  562. $rs['info'][0]['coin']=$info['coin'];
  563. setcaches($key,1,50);
  564. return $rs;
  565. }
  566. /**
  567. * 进入直播间
  568. * @desc 用于用户进入直播
  569. * @return int code 操作码,0表示成功
  570. * @return array info
  571. * @return string info[0].votestotal 直播映票
  572. * @return string info[0].barrage_fee 弹幕价格
  573. * @return string info[0].userlist_time 用户列表获取间隔
  574. * @return string info[0].chatserver socket地址
  575. * @return string info[0].nums 房间人数
  576. * @return string info[0].pull_url 播流地址
  577. * @return string msg 提示信息
  578. */
  579. public function enterRoom() {
  580. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  581. $uid=checkNull($this->uid);
  582. $token=checkNull($this->token);
  583. $liveuid=checkNull($this->liveuid);
  584. $city=checkNull($this->city);
  585. // $stream=checkNull($this->stream);
  586. $mobileid=checkNull($this->mobileid);
  587. $usernicename=checkNull($this->usernicename);
  588. if($uid>0){
  589. $checkToken=checkToken($uid,$token);
  590. if($checkToken==700){
  591. $rs['code'] = $checkToken;
  592. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  593. return $rs;
  594. }
  595. }
  596. $domain = new Domain_Live();
  597. /*$userinfo=getUserInfo($uid);
  598. if ($userinfo['id']<1){
  599. $userinfo['id'] = $uid;
  600. }*/
  601. $userinfo['id'] = $uid;
  602. $userinfo['user_nicename'] = $usernicename;
  603. if(!$city){
  604. $city='好像在火星';
  605. }
  606. $userinfo['city']=$city;
  607. // $stream2=explode('_',$stream);
  608. // $showid=$stream2[1];
  609. $contribution='0';
  610. if($showid && $uid>0){
  611. $contribution=$domain->getContribut($uid,$liveuid,$showid);
  612. }
  613. $userinfo['contribution'] = $contribution;
  614. /* 等级+100 保证等级位置位数相同,最后拼接1 防止末尾出现0 */
  615. $userinfo['sign']=$userinfo['contribution'].'.'.($userinfo['level']+100).'1';
  616. $userinfo['usertype'] = 30;
  617. if($uid<0){
  618. $userinfo['id']=$mobileid;
  619. $token=$mobileid;
  620. }
  621. DI()->redis -> set($token,json_encode($userinfo));
  622. // 一天后过期,自动删除
  623. $nowtime=time();
  624. $expiretime=$nowtime+60*60*24;
  625. if($expiretime > 0){
  626. DI()->redis->expire($token, $expiretime);
  627. }
  628. /* 用户列表 */
  629. $userlists=$this->getUserList($liveuid,$liveuid);
  630. $configpri=getConfigPri();
  631. $info=array(
  632. 'votestotal'=>$userlists['votestotal'],
  633. 'barrage_fee'=>$configpri['barrage_fee'],
  634. 'userlist_time'=>$configpri['userlist_time'],
  635. 'chatserver'=>$configpri['chatserver'],
  636. 'nums'=>$userlists['nums'],
  637. 'speak_limit'=>$configpri['speak_limit'],
  638. 'barrage_limit'=>$configpri['barrage_limit'],
  639. 'level'=>$userinfo['level']
  640. );
  641. $live_info=$domain->getLiveInfo($liveuid);
  642. $pull=$live_info['pull'];
  643. // if($live_info['isvideo']!=1){
  644. // $pull=PrivateKeyA('rtmp',$stream,0);
  645. // }
  646. // 获取主播的 头像=live_avatar , 名字=live_nicename
  647. $live_info_json = DI()->redis -> get('userinfo_'.$liveuid);
  648. // 检查值是否存在
  649. if ($live_info_json !== false) {
  650. $live_d = json_decode($live_info_json, true);
  651. $info['user_nicename'] = $live_d['user_nicename'];
  652. $info['live_avatar'] = $live_d['live_avatar'];
  653. } else {
  654. // 键不存在,输出提示信息
  655. // echo '指定的键在 Redis 中不存在';
  656. $rs['code'] = 404;
  657. $rs['msg'] = '请输入正常开播的房间号';
  658. return $rs;
  659. }
  660. $info['pull']=html_entity_decode($pull);
  661. $info['userlists']=$userlists['userlist'];
  662. /* 用户余额 */
  663. $domain2 = new Domain_User();
  664. $usercoin=$domain2->getBalance($uid);
  665. $info['coin']=(string)$usercoin['coin'];
  666. /** 敏感词集合*/
  667. $dirtyarr=array();
  668. if($configpri['sensitive_words']){
  669. $dirtyarr=explode(',',$configpri['sensitive_words']);
  670. }
  671. $info['sensitive_words']=$dirtyarr;
  672. $result = array_merge($live_d, $info);
  673. $rs['info'][0]=$result;
  674. return $rs;
  675. }
  676. /**
  677. * 用户列表
  678. * @desc 用于直播间获取用户列表
  679. * @return int code 操作码,0表示成功
  680. * @return array info
  681. * @return string info[0].userlist 用户列表
  682. * @return string info[0].nums 房间人数
  683. * @return string info[0].votestotal 主播映票
  684. * @return string info[0].guard_type 守护类型
  685. * @return string msg 提示信息
  686. */
  687. public function getUserLists() {
  688. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  689. $liveuid=checkNull($this->liveuid);
  690. $stream=checkNull($this->stream);
  691. $p=$this->p;
  692. /* 用户列表 */
  693. $info=$this->getUserList($liveuid,$stream,$p);
  694. $rs['info'][0]=$info;
  695. return $rs;
  696. }
  697. protected function getUserList($liveuid,$stream,$p=1) {
  698. /* 用户列表 */
  699. $n=1;
  700. $pnum=20;
  701. $start=($p-1)*$pnum;
  702. $list=array();
  703. $uidlist=DI()->redis -> zRevRange('user_'.$stream,$start,$pnum,true);
  704. foreach($uidlist as $k=>$v){
  705. $userinfo=getUserInfo($k);
  706. $info=explode(".",$v);
  707. $userinfo['contribution']=(string)$info[0];
  708. $list[]=$userinfo;
  709. }
  710. // if(!$list){
  711. // $list=array();
  712. // }
  713. $nums=DI()->redis->zCard('user_'.$stream);
  714. if(!$nums){
  715. $nums=0;
  716. }
  717. // $rs['userlist']=$list;
  718. $rs['nums']=(string)$nums;
  719. /* 主播信息 */
  720. $domain = new Domain_Live();
  721. $rs['votestotal']=$domain->getVotes($liveuid);
  722. return $rs;
  723. }
  724. /**
  725. * 弹窗
  726. * @desc 用于直播间弹窗信息
  727. * @return int code 操作码,0表示成功
  728. * @return array info
  729. * @return string info[0].consumption 消费总数
  730. * @return string info[0].votestotal 票总数
  731. * @return string msg 提示信息
  732. */
  733. public function getPop() {
  734. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  735. $uid=checkNull($this->uid);
  736. $liveuid=checkNull($this->liveuid);
  737. $touid=checkNull($this->touid);
  738. $info=getUserInfo($touid);
  739. if(!$info){
  740. $rs['code']=1002;
  741. $rs['msg']='用户信息不存在';
  742. return $rs;
  743. }
  744. $info['action']='0';
  745. $rs['info'][0]=$info;
  746. return $rs;
  747. }
  748. /**
  749. * 礼物列表
  750. * @desc 用于获取礼物列表
  751. * @return int code 操作码,0表示成功
  752. * @return array info
  753. * @return string info[0].coin 余额
  754. * @return array info[0].giftlist 礼物列表
  755. * @return string info[0].giftlist[].id 礼物ID
  756. * @return string info[0].giftlist[].type 礼物类型
  757. * @return string info[0].giftlist[].mark 礼物标识
  758. * @return string info[0].giftlist[].giftname 礼物名称
  759. * @return string info[0].giftlist[].needcoin 礼物价格
  760. * @return string info[0].giftlist[].gifticon 礼物图片
  761. * @return string msg 提示信息
  762. */
  763. public function getGiftList() {
  764. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  765. $uid=checkNull($this->uid);
  766. $token=checkNull($this->token);
  767. $checkToken=checkToken($uid,$token);
  768. if($checkToken==700){
  769. $rs['code'] = $checkToken;
  770. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  771. return $rs;
  772. }
  773. $domain = new Domain_Live();
  774. $giftlist=$domain->getGiftList();
  775. $domain2 = new Domain_User();
  776. $coin=$domain2->getBalance($uid);
  777. $rs['info'][0]['giftlist']=$giftlist;
  778. $rs['info'][0]['coin']=$coin['coin'];
  779. return $rs;
  780. }
  781. /**
  782. * 赠送礼物
  783. * @desc 用于赠送礼物
  784. * @return int code 操作码,0表示成功
  785. * @return array info
  786. * @return string info[0].gifttoken 礼物token
  787. * @return string info[0].level 用户等级
  788. * @return string info[0].coin 用户余额
  789. * @return string msg 提示信息
  790. */
  791. public function sendGift() {
  792. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  793. $uid=checkNull($this->uid);
  794. $token=checkNull($this->token);
  795. $liveuid=checkNull($this->liveuid);
  796. $stream=checkNull($this->stream);
  797. $giftid=checkNull($this->giftid);
  798. $giftcount=checkNull($this->giftcount);
  799. $touids=checkNull($this->touids);
  800. $checkToken=checkToken($uid,$token);
  801. if($checkToken==700){
  802. $rs['code'] = $checkToken;
  803. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  804. return $rs;
  805. }
  806. $domain = new Domain_Live();
  807. $giftlist=$domain->getGiftList();
  808. $gift_info=array();
  809. foreach($giftlist as $k=>$v){
  810. if($giftid == $v['id']){
  811. $gift_info=$v;
  812. }
  813. }
  814. if(!$gift_info){
  815. $rs['code']=1002;
  816. $rs['msg']='礼物信息不存在';
  817. return $rs;
  818. }
  819. $domain = new Domain_Live();
  820. $result=$domain->sendGift($uid,$liveuid,$stream,$giftid,$giftcount,$touids);
  821. if($result==1001){
  822. $rs['code']=1001;
  823. $rs['msg']='余额不足';
  824. return $rs;
  825. }else if($result==1002){
  826. $rs['code']=1002;
  827. $rs['msg']='礼物信息不存在';
  828. return $rs;
  829. }else if($result==1004){
  830. $rs['code']=1004;
  831. $rs['msg']='请选择接收礼物用户';
  832. return $rs;
  833. }
  834. $rs['info'][0]['gifttoken']=$result['gifttoken'];
  835. $rs['info'][0]['level']=$result['level'];
  836. $rs['info'][0]['coin']=$result['coin'];
  837. unset($result['gifttoken']);
  838. unset($result['level']);
  839. unset($result['coin']);
  840. DI()->redis -> set($rs['info'][0]['gifttoken'],json_encode($result['list']));
  841. return $rs;
  842. }
  843. /**
  844. * 发送弹幕
  845. * @desc 用于发送弹幕
  846. * @return int code 操作码,0表示成功
  847. * @return array info
  848. * @return string info[0].barragetoken 礼物token
  849. * @return string info[0].level 用户等级
  850. * @return string info[0].coin 用户余额
  851. * @return string msg 提示信息
  852. */
  853. public function sendBarrage() {
  854. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  855. $uid=checkNull($this->uid);
  856. $token=checkNull($this->token);
  857. $liveuid=checkNull($this->liveuid);
  858. $stream=checkNull($this->stream);
  859. $giftid=0;
  860. $giftcount=1;
  861. $content=checkNull($this->content);
  862. if($content==''){
  863. $rs['code'] = 1003;
  864. $rs['msg'] = '弹幕内容不能为空';
  865. return $rs;
  866. }
  867. $checkToken=checkToken($uid,$token);
  868. if($checkToken==700){
  869. $rs['code'] = $checkToken;
  870. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  871. return $rs;
  872. }
  873. $domain = new Domain_Live();
  874. $result=$domain->sendBarrage($uid,$liveuid,$stream,$giftid,$giftcount,$content);
  875. if($result==1001){
  876. $rs['code']=1001;
  877. $rs['msg']='余额不足';
  878. return $rs;
  879. }else if($result==1002){
  880. $rs['code']=1002;
  881. $rs['msg']='礼物信息不存在';
  882. return $rs;
  883. }
  884. $rs['info'][0]['barragetoken']=$result['barragetoken'];
  885. $rs['info'][0]['level']=$result['level'];
  886. $rs['info'][0]['coin']=$result['coin'];
  887. unset($result['barragetoken']);
  888. DI()->redis -> set($rs['info'][0]['barragetoken'],json_encode($result));
  889. return $rs;
  890. }
  891. /**
  892. * 主播映票
  893. * @desc 用于获取主播映票
  894. * @return int code 操作码,0表示成功
  895. * @return array info
  896. * @return string info[0].votestotal 用户总数
  897. * @return string msg 提示信息
  898. */
  899. public function getVotes() {
  900. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  901. $liveuid=checkNull($this->liveuid);
  902. $domain = new Domain_Live();
  903. $info=$domain->getVotes($liveuid);
  904. $rs['info'][0]=$info;
  905. return $rs;
  906. }
  907. /**
  908. * 用户余额
  909. * @desc 用于获取用户余额
  910. * @return int code 操作码,0表示成功
  911. * @return array info
  912. * @return string info[0].coin 余额
  913. * @return string msg 提示信息
  914. */
  915. public function getCoin() {
  916. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  917. $uid=checkNull($this->uid);
  918. $token=checkNull($this->token);
  919. $checkToken=checkToken($uid,$token);
  920. if($checkToken==700){
  921. $rs['code'] = $checkToken;
  922. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  923. return $rs;
  924. }
  925. $domain2 = new Domain_User();
  926. $coin=$domain2->getBalance($uid);
  927. $rs['info'][0]['coin']=$coin['coin'];
  928. return $rs;
  929. }
  930. /**
  931. * 检测房间状态
  932. * @desc 用于检测房间状态
  933. * @return int code 操作码,0表示成功
  934. * @return array info
  935. * @return string info[0].status 状态 0关1开
  936. * @return string msg 提示信息
  937. */
  938. public function checkLiveing() {
  939. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  940. $uid=checkNull($this->uid);
  941. $token=checkNull($this->token);
  942. $stream=checkNull($this->stream);
  943. $domain = new Domain_Live();
  944. $checkToken=checkToken($uid,$token);
  945. if($checkToken==700){
  946. //将主播关播
  947. $domain->stopRoom($uid,$stream);
  948. $rs['code'] = $checkToken;
  949. $rs['msg'] = '您的登陆状态失效,请重新登陆!';
  950. return $rs;
  951. }
  952. $info=$domain->checkLiveing($uid,$stream);
  953. $rs['info'][0]['status']=$info;
  954. return $rs;
  955. }
  956. /**
  957. * 获取直播信息
  958. * @desc 用于个人中心进入直播间获取直播信息
  959. * @return int code 操作码,0表示成功
  960. * @return array info 直播信息
  961. * @return string msg 提示信息
  962. */
  963. public function getLiveInfo() {
  964. $rs = array('code' => 0, 'msg' => '', 'info' => array());
  965. $liveuid=checkNull($this->liveuid);
  966. if($liveuid<1){
  967. $rs['code'] = 1001;
  968. $rs['msg'] = '参数错误';
  969. return $rs;
  970. }
  971. $domain2 = new Domain_Live();
  972. $info=$domain2->getLiveInfo($liveuid);
  973. if(!$info){
  974. $rs['code'] = 1002;
  975. $rs['msg'] = '直播已结束';
  976. return $rs;
  977. }
  978. $rs['info'][0]=$info;
  979. return $rs;
  980. }
  981. }