love_php/app/Models/InteractLive.php

600 lines
20 KiB
PHP
Raw Normal View History

2026-04-02 09:20:51 +08:00
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Http\Response\ResponseJson;
use App\Services\IMService;
use App\Models\InteractLiveChannel;
class InteractLive extends Model
{
use ResponseJson;
protected $fillable = [];
protected $guarded = [];
//自定定义消息类型
public const CHATMSGTYPE = [
'main_leave'=>8,
'send_gift'=>0,
];
/**
* 当前正在直播记录
* @return [type] [description]
*/
public function lastLiveLog()
{
//Builder $query, Model $parent, $foreignKey, $localKey
return $this->newHasOne(InteractLiveLog::whereNotNull('female_user_id')->whereNotNull('male_user_id')->where('is_over', 0)->orderBy('id', 'desc'), new InteractLiveLog, 'live_id', 'id');
}
/**
* 有女嘉宾的直播记录
*/
public function femaleLiveLog()
{
//Builder $query, Model $parent, $foreignKey, $localKey
return $this->newHasOne(InteractLiveLog::/*whereNotNull('female_user_id')->*/where('is_over', 0)->orderBy('id', 'desc'), new InteractLiveLog, 'live_id', 'id');
}
/**
* 空闲直播
* @return [type] [description]
*/
public function leisureLiveLog()
{
//Builder $query, Model $parent, $foreignKey, $localKey
return $this->newHasOne(InteractLiveLog::where('is_over', 0)->where(function($sql){
$sql->whereNull('female_user_id')->orWhereNull('male_user_id');
})->orderBy('id', 'desc'), new InteractLiveLog, 'live_id', 'id');
}
//直播记录
public function liveLogs()
{
return $this->hasMany(InteractLiveLog::class, 'live_id', 'id');
}
//红娘信息
public function matchMaker()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
//踢人记录
public function banLogs()
{
return $this->hasMany(InteractLiveBanLog::class, 'live_id', 'id');
}
public function channels()
{
return $this->hasMany(InteractLiveChannel::class, 'live_id', 'id');
}
public function members()
{
return $this->belongsToMany(User::class, 'interact_live_members', 'live_id');
}
public function memberLogs()
{
return $this->hasMany(InteractLiveMember::class, 'live_id', 'id');
}
public function applyLogs()
{
return $this->hasMany(InteractApplyLog::class, 'live_id', 'id');
}
public function clickNumKey()
{
return 'live_'.$this->id.'_click_num';
}
/**
* 创建聊天室
* @param [type] $creator [description]
* @param [type] $name [description]
* @param [type] $announcement [description]
* @return [type] [description]
*/
public function createChatRoom($creator, $name, $announcement='', $broadcasturl='', $ext=[], $queuelevel=0)
{
\Log::info('创建聊天室');
try {
// $im = new IMService(env('IM_APP_KEY'), env('IM_APP_SECRET'));
// $result = $im->chatRoomCreate($creator, $name, $announcement, $broadcasturl, $ext, $queuelevel);
// if (empty($result) || $result['code'] != 200) {//失败
// \Log::info($result);
// throw new \Exception("创建IM聊天室请求失败", 1);
// }
// return $result['chatroom'];
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* [createChannel 创建音视频房间]
* @param [type] $type [description]
* @param [type] $channelName [description]
* @param [type] $accid [description]
* @param integer $webrtc [description]
* @param array $selfconfig [description]
* @param array $roomconfig [description]
* @return [type] [description]
*/
public function createChannelRoom($type, $channelName, $accid=null, $webrtc=0, $selfconfig=[], $roomconfig='')
{
\Log::info('创建音视频');
try {
$im = new IMService(env('IM_APP_KEY'), env('IM_APP_SECRET'));
$result = $im->createChannel($type, $channelName, $accid, $webrtc, $selfconfig, $roomconfig);
if (empty($result) || $result['code'] != 200) {//失败
throw new \Exception("创建音视频房间请求失败", 1);
}
\Log::info('创建音视频成功');
return $result['cid'];
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* [createChannel 创建音视频房间v2]
* @param [type] $type [description]
* @param [type] $channelName [description]
* @param [type] $accid [description]
* @param integer $webrtc [description]
* @param array $selfconfig [description]
* @param array $roomconfig [description]
* @return [type] [description]
*/
public function createChannelRoomV2($type, $channelName, $accid=null, $webrtc=0, $selfconfig=[], $roomconfig='', $version=1)
{
\Log::info('创建音视频');
try {
$im = new IMService(env('IM_APP_KEY'), env('IM_APP_SECRET'));
switch ($version){
case 1:
$result = $im->createChannel($type, $channelName, $accid, $webrtc, $selfconfig, $roomconfig);
break;
case 2:
$result = $im->createChannelV2($channelName, $accid);
break;
default:
$result = '';
break;
}
if (empty($result) || $result['code'] != 200) {//失败
throw new \Exception("创建音视频房间请求失败", 1);
}
\Log::info('创建音视频成功');
return $result['cid'];
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* 聊天室用户列表
* @param [type] $roomid [description]
* @param [type] $type [description]
* @param [type] $endtime [description]
* @param [type] $limit [description]
* @return [type] [description]
*/
public function chatroomMembers($roomid, $type, $endtime, $limit)
{
\Log::info('聊天室成员列表');
try {
$im = new IMService(env('IM_APP_KEY'), env('IM_APP_SECRET'));
$result = $im->chatroomMembers($roomid, $type, $endtime, $limit);
if (empty($result) || $result['code'] != 200) {//失败
throw new \Exception("分页获取成员请求失败", 1);
}
return $result['desc']['data'];
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* 创建直播流地址
* @param [type] $name [description]
* @param [type] $type [description]
* @return [type] [description]
*/
public function createLiveChannel($name, $type)
{
\Log::info('创建直播流');
try {
//判断数据是否有对应流
$channel = $this->channel($type);
if (empty($channel)) {
$im = new IMService();
$result = $im->channelCreate($name,0);
if (empty($result) || $result['code'] != 200) {//失败
throw new \Exception("创建直播流失败", 1);
}
$ret = $result['ret'];
//创建直播流
$channel = $this->channels()->create([
'name'=>$name,
'type'=>$type,
'push_url'=>$ret['pushUrl'],
'http_pull_url'=>$ret['httpPullUrl'],
'hls_pull_url'=>$ret['hlsPullUrl'],
'rtmp_pull_url'=>$ret['rtmpPullUrl'],
'cid'=>$ret['cid']
]);
}
return $channel;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* [addRtmpTask 增加一个房间推流任务]
* @param [type] $channelName [description]
*/
public function addRtmpTask($mian_user_id, $male_user_id=0, $female_user_id=0)
{
try {
\Log::info('增加一个房间推流任务');
$live_name = $this->name;
$channel = $this->channel('main');
//加入直播间 todo
$task = [
"taskId"=>$channel->cid,
"streamUrl"=>$channel->push_url,
"layoutMode"=>"M-4",
"record"=>true,
"layoutPara"=>[
"version"=>0,
"set_host_as_main"=>false,
"host_area"=>[
"adaption"=>1,
"position_x"=>2500,
"position_y"=>0,
"width_rate"=>5000,
"height_rate"=>5000,
'accid'=>$this->user_id
],
"non_adaptive"=>true,
"n_host_area_number"=>2,
"special_show_mode"=>true,
"main_width"=>1200,
"main_height"=>1200,
"background"=>[
"rgb_r"=>255,
"rgb_g"=>1,
"rgb_b"=>1
],
"n_host_area_0"=>[
"height_rate"=>5000,
"width_rate"=>5000,
"position_x"=>0,
"position_y"=>5000,
"adaption"=>1,
'accid'=>$male_user_id?:''
],
"n_host_area_1"=>[
"height_rate"=>5000,
"width_rate"=>5000,
"position_x"=>5000,
"position_y"=>5000,
"adaption"=>1,
'accid'=>$female_user_id?:''
]
]
];
$task = json_encode($task, JSON_UNESCAPED_UNICODE);
//增加一个房间推流任务
$im = new IMService();
$im->addRtmpTask($live_name, 0, $task);
\Log::info('增加一个房间推流任务成功');
return true;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* [addRtmpTask 增加一个房间推流任务V2]
* @param [type] $channelName [description]
*/
public function addRtmpTaskV2($mian_user_id)
{
try {
\Log::info('增加一个房间推流任务');
$live_name = $this->name;
$channel = InteractLiveChannel::where('live_id', $this->id)->first();
if (empty($channel)) throw new \Exception("直播频道不存在", 1);
//加入直播间 todo
$task = [
"taskId"=>$channel->cid,
"streamUrl"=>$channel->push_url,
"layoutMode"=>"M-0",
"record"=>true,
"accid"=>$this->user_id,
];
//增加一个房间推流任务
$im = new IMService();
$result = $im->addRtmpTaskV2($live_name, $this->channel_id, $task);
if (empty($result) || $result['code'] != 200) {//失败
throw new \Exception("增加一个房间推流任务失败", 1);
}
\Log::info('增加一个房间推流任务成功');
return true;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function updateRtmpTask($mian_user_id, $male_user_id=0, $female_user_id=0)
{
try {
\Log::info('修改一个房间推流任务');
$live_name = $this->name;
$channel = $this->channel('main');
//修改一个房间推流任务
$opeJson = [
"taskId"=>$channel->cid,
"streamUrl"=>$channel->push_url,
"layoutMode"=>"M-4",
"record"=>true,
"layoutPara"=>[
"version"=>0,
"set_host_as_main"=>false,
"host_area"=>[
"adaption"=>1,
"position_x"=>2500,
"position_y"=>0,
"width_rate"=>5000,
"height_rate"=>5000,
'accid'=>$this->user_id
],
"non_adaptive"=>true,
"n_host_area_number"=>2,
"special_show_mode"=>true,
"main_width"=>1200,
"main_height"=>1200,
"background"=>[
"rgb_r"=>204,
"rgb_g"=>204,
"rgb_b"=>204
],
"n_host_area_0"=>[
"height_rate"=>5000,
"width_rate"=>5000,
"position_x"=>0,
"position_y"=>5000,
"adaption"=>1,
'accid'=>$male_user_id?:'',
],
"n_host_area_1"=>[
"height_rate"=>5000,
"width_rate"=>5000,
"position_x"=>5000,
"position_y"=>5000,
"adaption"=>1,
'accid'=>$female_user_id?:'',
]
]
];
$im = new IMService();
$result = $im->updateRtmpTask($live_name, $type=0, $ope=1, json_encode($opeJson));
if (empty($result) || $result['code'] != 200) {
throw new \Exception("修改一个房间推流任务失败", 1);
}
return true;
} catch (Exception $e) {
$this->getError($e);
return false;
}
}
/**
* 直播流
* @param [type] $type [description]
* @return [type] [description]
*/
public function channel($type)
{
return $this->channels()->where('type', $type)->where('live_id', $this->id)->first();
}
/**
* 删除直播流
* @param [type] $type [description]
* @return [type] [description]
*/
public function deleteLiveChannel()
{
try {
\Log::info('删除直播流');
//查找fl直播流
$channel = $this->channel('main');
if (empty($channel)) {
return true;
}
$im = new IMService();
$result = $im->channelDelete($channel->cid);
if (empty($result) || $result['code'] != 200) {//失败
throw new \Exception("删除直播流失败", 1);
}
$channel->delete();
return true;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function removeRtmpTask()
{
try {
\Log::info('删除一个房间推流任务');
$live_name = $this->name;
$channel = $this->channel('main');
// \Log::info('房间号名称'.$live_name);
//查找fl直播流
if (empty($channel)) {
return false;
}
//关闭房间推流
$im = new IMService();
$result = $im->removeRtmpTask($live_name, $type=0, $channel->cid);
if (empty($result) || $result['code'] != 200) {//失败
throw new \Exception("删除一个房间推流任务失败", 1);
}
\Log::info('删除一个房间推流任务成功');
return true;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function getRtmpTask()
{
\Log::info('查看单个房间推流任务');
$live_name = $this->name;
$channel = $this->channel('main');
if (empty($channel)) {
return false;
}
try {
\Log::info('房间号名称'.$live_name);
//查看房间推流
$im = new IMService();
$result = $im->getRtmpTaskV2($live_name, $channel->id, $channel->cid);
if (empty($result) || $result['code'] == 404) {//失败
return false;
}elseif (empty($result) || ($result['code'] != 200 && $result['code'] != 404)) {
throw new \Exception("查看单个房间推流任务失败", 1);
}
\Log::info('查看单个房间推流任务成功');
return $result['rtmpTask'];
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function getRtmpTaskList()
{
$live_name = $this->name;
$channel = $this->channel('main');
if (empty($channel)) {
return false;
}
try {
//查看房间推流
$im = new IMService();
$result = $im->getRtmpTaskList($live_name, $type=0);
if (empty($result) && $result['code'] != 200) {//失败
return false;
}
return $result;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function checkInteractLive()
{
try {
$im = new IMService();
$result = $im->checkInteractLive($this->channel_id);
if (empty($result) || $result['code'] != '200') {
return false;
}
return true;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function channelRoom()
{
try {
if (empty($this->channel_id)) return false;
$im = new IMService();
$result = $im->liveRoom($this->channel_id);
if (is_array($result) && isset($result['cid'])) {
return $result;
}
return false;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* [chatroomLineMembers 批量查询聊天室在线成员]
* @return [type] [description]
*/
public function chatroomLineMembers($accids)
{
try {
$im = new IMService();
$result = $im->chatroomLineMembers($this->chat_room_id, $accids);
if (empty($result) || $result['code'] != 200) {
throw new \Exception("批量获取在线用户失败", 1);
}
return $result['desc']['data'];
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
/**
* 发送聊天室消息
* @param [type] $roomid [description]
* @param [type] $msgId [description]
* @param [type] $fromAccid [description]
* @param [type] $msgType [description]
* @param [type] $attach [description]
* @return [type] [description]
*/
public function chatroomSendMsg($fromAccid, $msgType, $attach)
{
try {
$roomid = $this->chat_room_id;
$msgId = $fromAccid.time();
$im = new IMService();
$result = $im->chatroomSendMsg($roomid, $msgId, $fromAccid, $msgType, $attach);
if (empty($result) || $result['code'] != 200) throw new \Exception("发送聊天室消息失败", 1);
return true;
} catch (\Exception $e) {
$this->getError($e);
return false;
}
}
public function scopeInLive($query)
{
return $query->where('in_live', 1);
}
}