route('login');
}
$userLogged = User::where('id', '=', Auth::id())->get()->first();
$allNotifications = DB::table('notifications')->orderBy('id','desc')->limit('3')->get();
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$playlists = DB::table('playlists')->where('port','=',$siteData->stream_port)->orderBy('name','asc')->get();
$schedules = DB::table('playlists_schedules')->where('port','=',$siteData->stream_port)->get();
/* a capa e buscada pelo navegador, entao a tela precisa saber se esta ligada */
$siteSettings = DB::connection('mysql_site_' . session('serverID'))->table('settings')
->where('site_id', '=', session('siteID'))->first();
return view('radio.home', ['userLogged' => $userLogged , 'allNotifications' => $allNotifications, 'topHref' => 'radio',
'siteData' => $siteData, 'streamData' => $getStreamDetails, 'getServerDetails' => $getServerDetails, 'playlists' => $playlists,
'schedules' => $schedules, 'coverOn' => ($siteSettings->metadata_cover ?? '1') !== '0']);
}
public function ajaxListeners()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$set = DB::table('settings')->where('id','=',1)->get()->first();
$headers = array(
'Content-Type:application/json',
'Authorization: Basic ' . base64_encode($set->master_user.":".$set->master_pass)
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://".$getServerDetails->ip.":".$getStreamDetails->port."/admin/listclients");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'BRASCASTX');
$resultado = curl_exec($ch);
curl_close($ch);
$resultado = xml_entity_decode($resultado);
$xml = @simplexml_load_string(utf8_encode($resultado));
if(!$xml){
return '
0
'.__('radio.home_listeners_multiple').'
';
}else{
return ''.(!$xml->source->listeners ? '0' : $xml->listeners).'
'.($xml->source->listeners == 1 ? __('radio.home_listeners_unique') : __('radio.home_listeners_multiple')).'
';
}
}
public function actionAutoDJ()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/data/history.php?p='.$getStreamDetails->port);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, 'BRASCASTX');
$jsonGetInfo = curl_exec($ch);
curl_close($ch);
$dataInfo = json_decode($jsonGetInfo,true);
$finalCodecInfo = ($getStreamDetails->autodj_codec == 'aac' ? 'AAC+' : 'MP3').'('.$getStreamDetails->autodj_bitrate.'kbps, Stereo, 44.1kHz)';
$rawTime = $getStreamDetails->autodj_time ?? null;
if ($rawTime) {
$timestamp = strtotime($rawTime);
$locale = Cookie::get('locale', 'pt');
$finalBroadcastTime = ($locale === 'pt')
? date('d/m/Y H:i', $timestamp)
: date('Y-m-d H:i', $timestamp);
} else {
$finalBroadcastTime = '--';
}
$getCurrentPlaylist = DB::table('playlists')->where('id','=',$getStreamDetails->current_playlist_id)->get()->first();
$playlists = DB::table('playlists')->where('port','=',$siteData->stream_port)->orderBy('name','asc')->get();
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_URL,'https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/data/info.php?p='.$getStreamDetails->port);
$result=curl_exec($ch);
$dataAutoDJInfo = json_decode($result, true);
if (session('siteID') == '25158') {
// return dd($result);//'https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/data/info.php?p='.$getStreamDetails->port;
}
curl_close($ch);
return view('radio.ajax.autodj',['getStreamDetails' => $getStreamDetails,'dataInfo' => $dataInfo, 'finalCodecInfo' => $finalCodecInfo, 'finalBroadcastTime' => $finalBroadcastTime,
'getCurrentPlaylist' => $getCurrentPlaylist, 'dataAutoDJInfo' => $dataAutoDJInfo, 'playlists' => $playlists]);
}
public function actionLive()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$djConnected = DB::table('djs')->where('port','=',$siteData->stream_port)->where('active','=','1')->get();
$codecLive = 'AAC+';
$bitrateLive = '128';
if($djConnected->count()){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://".$getServerDetails->ip.":".$getStreamDetails->port."/status-json.xsl");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_USERAGENT, 'BRASCASTX');
$result = json_decode(curl_exec($ch));
curl_close($ch);
$types = array('audio/aacp' => 'AAC+', 'audio/mpeg' => 'MP3','audio/aac' => 'AAC+',);
$bitrateLive = (isset($result->icestats->source[0]->bitrate) ? $result->icestats->source[0]->bitrate : '128');
$codecLive = (isset($result->icestats->source[0]->server_type) ? $types[$result->icestats->source[0]->server_type] : 'AAC+');
}
return view('radio.ajax.aovivo',['djConnected' => $djConnected , 'getStreamDetails' => $getStreamDetails, 'bitrateLive' => $bitrateLive,
'codecLive' => $codecLive]);
}
public function actionRelay()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
return view('radio.ajax.relay',['getStreamDetails' => $getStreamDetails]);
}
public function actionManu()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
return view('radio.ajax.manutention',['getStreamDetails' => $getStreamDetails]);
}
public function execAction($type = null,$action = null,$param = null)
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
if(!$type){ return false; }
$allTypes = array("SkipSong", "AutoDJControl","ReloadPlaylist","StopRelay","StopLive");
if (!in_array($type, $allTypes)){return false;}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
if($getStreamDetails->status == '2'){
return array("result"=>true,"message"=>"O AutoDJ não pode iniciar pois está suspenso.");
}
if($type == 'AutoDJControl' && $action == 'start'){
$isLiveConnected = DB::table('djs')->where('port','=',$siteData->stream_port)->where('active','=','1')->get()->count();
if($isLiveConnected){
return array("result"=>true,"message"=>"O AutoDJ não pode iniciar pois existe uma transmissão ao vivo conectada.");
}else{
$getPlaylistData = DB::table('playlists')->where('id','=',$param)->get()->first();
$param = ($getPlaylistData->id ? $getPlaylistData->id : null);
DB::table('relays')->where('port','=',$siteData->stream_port)->update(['active' => '0']);
DB::table('streamings')->where('port','=',$siteData->stream_port)->update([
'current_playlist_id' => $param,
'current_playlist_type' => 0,
'autodj_time' => now()
]);
setLog($siteData->stream_port, 'AutoDJ ligado manualmente', request()->ip());
$message = 'Playlist iniciada com sucesso!';
}
}elseif($type == 'AutoDJControl' && $action == 'change'){
$expParam = explode('|',$param);
$nparam = (count($expParam) > 1 ? $expParam[0] : null);
$getPlaylistData = DB::table('playlists')->where('id','=',$nparam)->get()->first();
$param = (isset($getPlaylistData->id) ? $getPlaylistData->id.'|'.$expParam[1] : null);
DB::table('streamings')->where('port','=',$siteData->stream_port)->update([
'current_playlist_id' => $getPlaylistData->id,
'current_playlist_type' => 0,
'autodj_time' => now()
]);
setLog($siteData->stream_port, 'Playlist trocada manualmente', request()->ip());
$message = __('radio.home_msg_actions_playlist_changed');
}elseif($type == 'AutoDJControl' && $action == 'stop'){
DB::table('streamings')->where('port','=',$siteData->stream_port)->update(['current_playlist_id' => null ]);
setLog($siteData->stream_port, 'AutoDJ desligado manualmente', request()->ip());
$message = __('radio.home_msg_actions_autodj_stopped');
}elseif($type == 'ReloadPlaylist'){
setLog($siteData->stream_port, 'Playlist reiniciada manualmente', request()->ip());
$message = __('radio.home_msg_actions_playlist_reloaded');
}elseif($type == 'StopRelay'){
$message = __('radio.home_msg_actions_relay_stopped');
$actualRelay = DB::table('relays')->where('port','=',$siteData->stream_port)->where('active','=','1')->first();
if ($actualRelay) { setLog($siteData->stream_port, 'Desligou a retransmissão manualmente: '. $actualRelay->id, request()->ip());}
}elseif($type == 'StopLive'){
$message = 'Locutor desconectado com sucesso';
setLog($siteData->stream_port, 'Locutor desconectado manualmente', request()->ip());
}else{
setLog($siteData->stream_port, 'Áudio pulado manualmente', request()->ip());
$message = __('radio.home_msg_actions_audio_skiped');
}
if($type == 'StopRelay'){
$post = [
'p' => $siteData->stream_port,
'ac' => 'stop'
];
$ch = curl_init('https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/stream/ManageRelay.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "CURL");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Hash: 4BEAD0A3736F606092EADB5540B277966C2735F98294BD50547DB391ABB37E99",
"Secret: streamingbrascastsrvr"
]);
$result = curl_exec($ch);
curl_close($ch);
$actualRelay = DB::table('relays')->where('port','=',$siteData->stream_port)->where('active','=','1')->first();
$update = [
'active' => '0'
];
if ($actualRelay->type == '1') { // só limpa se for tipo 1 (semanal), tipo 2 mantem a hora e inicio para o usuario atualizar posteriormente
$update['start_time'] = null;
$update['end_time'] = null;
} else if ($actualRelay->type == '2'){
$update['always'] = '0'; // tipo 2 quer dizer que tem fim, então coloca o always como 0 para garantir;
}
DB::table('relays')->where('id','=',$actualRelay->id)->update($update);
}if($type == 'StopLive'){
$post = [
'p' => $siteData->stream_port,
'ac' => 'stop'
];
$ch = curl_init('https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/stream/LiveControl.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "CURL");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Hash: 4BEAD0A3736F606092EADB5540B277966C2735F98294BD50547DB391ABB37E99",
"Secret: streamingbrascastsrvr"
]);
$result = curl_exec($ch);
curl_close($ch);
DB::table('djs')->where('port','=',$siteData->stream_port)->where('active','=','1')->update(['active' => '0']);
}else{
$ch = curl_init('https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/stream/'.$type.'.php?p='.$getStreamDetails->port.'&p_dj='.$getStreamDetails->autodj_port.($action ? '&a='.$action : '').($param ? '&o='.$param : ''));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT,120);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($ch, CURLOPT_USERAGENT, "CURL");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Hash: 4BEAD0A3736F606092EADB5540B277966C2735F98294BD50547DB391ABB37E99",
"Secret: streamingbrascastsrvr"
]);
$result = curl_exec($ch);
curl_close($ch);
}
$array = array("result"=>$result,"message"=>$message,"ap"=>$param);
return $array;
}
/*
public function statusInfo()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$haveDJConnected = DB::table('djs')->where('port','=',$siteData->stream_port)->where('active','=','1')->get()->count();
$relayConected = DB::table('relays')->where('port','=',$siteData->stream_port)->where('active','=','1')->get()->count();
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_URL,'https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/data/info.php?p='.$getStreamDetails->port);
$result=curl_exec($ch);
$dataAutoDJInfo = json_decode($result,true);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$verifyDjConnected = (isset($dataAutoDJInfo['status_live']) && $dataAutoDJInfo['status_live'] == 'on' ? 1 : ($haveDJConnected >= 1 ? 1 : 0));
if($haveDJConnected && $dataAutoDJInfo['status_autodj'] == 'on' && $dataAutoDJInfo['status_live'] == 'off'){
DB::table('djs')->where('port','=',$siteData->stream_port)->update([
'active' => '0'
]);
}
if($httpcode != '200'){
return array("iconblock01"=>"opacity-50 text-danger","block01_h1" => "Manutenção", "block01_h2" => '',
"iconblock02"=>null, "block02_h1" => null,"block02_h2" => null,
"msgAutoDJ" => false,"act" => "block01-tab","btnact" => "btn-block01-tab","target01"=>"block01-tab","target02"=>"block02-tab","relay" => null);
}elseif($dataAutoDJInfo['status_autodj'] == 'on' && $relayConected == '0' && $verifyDjConnected == 0){
return array("iconblock01"=>"blink","block01_h1" => __('radio.home_block_item_autodj'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"opacity-50 text-danger", "block02_h1" => __('radio.home_block_item_live'),"block02_h2" => __('radio.home_block_item_type_1'),
"msgAutoDJ" => false,"act" => "block01-tab","btnact" => "btn-block01-tab","target01"=>"block01-tab","target02"=>"block02-tab","relay" => null);
}elseif($dataAutoDJInfo['status_autodj'] == 'on' && $relayConected == '0' && $verifyDjConnected == 1){
return array("iconblock01"=>"blink","block01_h1" => __('radio.home_block_item_live'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"text-primary", "block02_h1" => __('radio.home_block_item_autodj'),"block02_h2" => __('radio.home_block_item_type_3'),
"msgAutoDJ" => true,"act" => "block02-tab","btnact" => "btn-block01-tab","target01"=>"block02-tab","target02"=>"block01-tab","relay" => null);
}elseif($dataAutoDJInfo['status_autodj'] == 'off' && $relayConected == '0' && $verifyDjConnected == 1){
return array("iconblock01"=>"blink","block01_h1" => __('radio.home_block_item_live'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"opacity-50 text-danger", "block02_h1" => __('radio.home_block_item_autodj'),"block02_h2" => __('radio.home_block_item_type_1'),
"msgAutoDJ" => false,"act" => "block02-tab","btnact" => "btn-block01-tab","target01"=>"block02-tab","target02"=>"block01-tab","relay" => null);
}elseif($dataAutoDJInfo['status_autodj'] == 'on' && $relayConected >= '1' && $verifyDjConnected == 0){
return array("iconblock01"=>"text-danger","block01_h1" => __('radio.home_block_item_live'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"text-primary", "block02_h1" => __('radio.home_block_item_autodj'),"block02_h2" => __('radio.home_block_item_type_3'),
"msgAutoDJ" => true,"act" => "block03-tab","btnact" => "btn-block03-tab","target01"=>"block03-tab","target02"=>"block01-tab","relay" => true);
}else{
return array("iconblock01"=>"text-danger","block01_h1" => __('radio.home_block_item_autodj'), "block01_h2" => __('radio.home_block_item_type_1'),
"iconblock02"=>"opacity-50 text-danger", "block02_h1" => __('radio.home_block_item_live'),"block02_h2" => __('radio.home_block_item_type_1'),
"msgAutoDJ" => false,"act" => "block01-tab","btnact" => "btn-block01-tab","target01"=>"block01-tab","target02"=>"block02-tab","relay" => null);
}
}
*/
public function statusInfo()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$haveDJConnected = DB::table('djs')->where('port','=',$siteData->stream_port)->where('active','=','1')->get()->count();
$relayConected = DB::table('relays')->where('port','=',$siteData->stream_port)->where('active','=','1')->get()->count();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://'.$getServerDetails->ip.':'.$getStreamDetails->port.'/status-json.xsl');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8);
curl_setopt($ch, CURLOPT_TIMEOUT, 8);
curl_setopt($ch, CURLOPT_USERAGENT, 'BRASCASTX');
$result = json_decode(curl_exec($ch));
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$autoDJStatus = 'off';
$verifyDjConnected = ($haveDJConnected >= 1 ? 1 : 0);
if (isset($result->icestats->source) && stripos(json_encode($result->icestats->source),'/autodj') !== false || isset($result->icestats->source) && stripos(json_encode($result->icestats->source[0]->server_name),'/autodj') !== false) {
$autoDJStatus = 'on';
}
/*if($haveDJConnected && $dataAutoDJInfo['status_autodj'] == 'on' && $dataAutoDJInfo['status_live'] == 'off'){
DB::table('djs')->where('port','=',$siteData->stream_port)->update([
'active' => '0'
]);
}*/
if($autoDJStatus == 'on' && $relayConected == '0' && $verifyDjConnected == 0){
return array("iconblock01"=>"blink","block01_h1" => __('radio.home_block_item_autodj'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"opacity-50 text-danger", "block02_h1" => __('radio.home_block_item_live'),"block02_h2" => __('radio.home_block_item_type_1'),
"msgAutoDJ" => false,"act" => "block01-tab","btnact" => "btn-block01-tab","target01"=>"block01-tab","target02"=>"block02-tab","relay" => null, 'info' => 1);
}elseif($autoDJStatus == 'on' && $relayConected == '0' && $verifyDjConnected == 1){
return array("iconblock01"=>"blink","block01_h1" => __('radio.home_block_item_live'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"text-primary", "block02_h1" => __('radio.home_block_item_autodj'),"block02_h2" => __('radio.home_block_item_type_3'),
"msgAutoDJ" => true,"act" => "block02-tab","btnact" => "btn-block01-tab","target01"=>"block02-tab","target02"=>"block01-tab","relay" => null, 'info' => 2);
}elseif($autoDJStatus == 'off' && $relayConected == '0' && $verifyDjConnected == 1){
return array("iconblock01"=>"blink","block01_h1" => __('radio.home_block_item_live'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"opacity-50 text-danger", "block02_h1" => __('radio.home_block_item_autodj'),"block02_h2" => __('radio.home_block_item_type_1'),
"msgAutoDJ" => false,"act" => "block02-tab","btnact" => "btn-block01-tab","target01"=>"block02-tab","target02"=>"block01-tab","relay" => null, 'info' => 3);
}elseif($autoDJStatus == 'on' && $relayConected >= '1' && $verifyDjConnected == 0){
return array("iconblock01"=>"text-danger","block01_h1" => __('radio.home_block_item_live'), "block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02"=>"text-primary", "block02_h1" => __('radio.home_block_item_autodj'),"block02_h2" => __('radio.home_block_item_type_3'),
"msgAutoDJ" => true,"act" => "block03-tab","btnact" => "btn-block03-tab","target01"=>"block03-tab","target02"=>"block01-tab","relay" => true, 'info' => 4);
}elseif($autoDJStatus == 'on' && $relayConected >= '1' && $verifyDjConnected == 1){
return array(
"iconblock01" => "blink",
"block01_h1" => __('radio.home_block_item_live'),
"block01_h2" => __('radio.home_block_item_type_2'),
"iconblock02" => "text-primary",
"block02_h1" => __('radio.home_block_item_autodj'),
"block02_h2" => "Relay em 2º plano",
"msgAutoDJ" => true,
"act" => "block02-tab",
"btnact" => "btn-block01-tab",
"target01" => "block02-tab",
"target02" => "block01-tab",
"relay" => false,
"msgRelay" => "Relay em 2º plano",
'info' => 5
);
}else{
return array("iconblock01"=>"text-danger","block01_h1" => __('radio.home_block_item_autodj'), "block01_h2" => __('radio.home_block_item_type_1'),
"iconblock02"=>"opacity-50 text-danger", "block02_h1" => __('radio.home_block_item_live'),"block02_h2" => __('radio.home_block_item_type_1'),
"msgAutoDJ" => false,"act" => "block01-tab","btnact" => "btn-block01-tab","target01"=>"block01-tab","target02"=>"block02-tab","relay" => null, 'info' => 6);
}
}
public function infoCurrent()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch1, CURLOPT_TIMEOUT, 10);
curl_setopt($ch1, CURLOPT_URL,'https://'.$getServerDetails->name.'.'.env('BASE_SERVER_URL','brascast.com').'/bras_api/data/info.php?p='.$getStreamDetails->port);
$result1=curl_exec($ch1);
$dataStatus = json_decode($result1,true);
curl_close($ch1);
if(!isset($dataStatus) || $dataStatus['status_live'] == 'on' || $dataStatus['status_autodj'] != 'on' && $dataStatus['status_live'] != 'on'){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://".$getServerDetails->ip.":".$getStreamDetails->port."/status-json.xsl");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_USERAGENT, 'BRASCASTX');
$resultado = json_decode(curl_exec($ch));
curl_close($ch);
$cur = (isset($resultado->icestats->source[0]->title) ? $resultado->icestats->source[0]->title : '');
$dataLive = json_encode(array('now' => $cur, 'next' => ''));
$dataAutoDJInfo = json_decode($dataLive, true);
}else if(!isset($dataStatus) || $dataStatus['status_autodj'] != 'on') {
$dataAutoDJInfo = json_encode(array('now' => '', 'next' => ''));
}else{
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_URL, 'https://' . $getServerDetails->name . '.' . env('BASE_SERVER_URL', 'brascast.com') . '/bras_api/data/current.php?p=' . $getStreamDetails->port);
$result = curl_exec($ch);
$dataAutoDJInfo = json_decode($result, true);
curl_close($ch);
}
return str_replace('\\','',$dataAutoDJInfo);
}
public function getCoverOld()
{
if(Auth::check() === false){
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$siteSettings = DB::connection('mysql_site_'.session('serverID'))->table('settings')->where('site_id','=',session('siteID'))->first();
$getStreamDetails = DB::table('streamings')->where('port','=',$siteData->stream_port)->get()->first();
$getServerDetails = DB::table('servers')->where('id','=',$getStreamDetails->server_id)->get()->first();
$finalCover = null;
if (isset($siteSettings) && $siteSettings->metadata_cover == '0') {
return response()->json(['cover' => $finalCover]);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://".$getServerDetails->ip.":".$getStreamDetails->port."/status-json.xsl");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_USERAGENT, 'BRASCASTX');
$resultado = json_decode(curl_exec($ch));
curl_close($ch);
$cur = (isset($resultado->icestats->source[0]->title) ? $resultado->icestats->source[0]->title : null);
$cur = str_replace('_',' ',$cur);
$exp = explode('-',$cur);
$defaultCont = array('Hora Certa');
if(strpos($cur, ' - Completo') || strpos($cur, ' - Parte ')) {
$expCur = explode('-',$cur);
$finalCover = env('STORAGE_URL').'covers/default/'.md5($expCur[0]).'.jpg';
}else{
$defaultLive = array('PROGRAMAÇÃO AO VIVO','PROGRAMACAO AO VIVO','PROGRAMAÇÃO AOVIVO','PROGRAMACAO AOVIVO','ㅤ');
if(in_array($cur,$defaultLive)){
$finalCover = env('STORAGE_URL').'covers/default/5b36dd0016ac6a4f4df796162752812a.jpg';
}else if(in_array($cur,$defaultCont)){
$finalCover = env('STORAGE_URL').'covers/default/'.md5($cur).'.jpg';
}else{
$url = env('STORAGE_URL').'covers/'.md5($getStreamDetails->port).'/'.md5($cur).'.jpg';
$headers = @get_headers($url);
if(isset($headers[0]) && strpos($headers[0],'200')){
$finalCover = $url;
}else{
$expPodcast = explode(' - ', $cur);
$podcastName = trim($expPodcast[0]);
$podcast = DB::connection('mysql_site_'.session('serverID'))
->table('podcasts')
->where('site_id', '=', session('siteID'))
->whereRaw('TRIM(name) = ?', [$podcastName])
->first();
if($podcast){
$finalCover = env('STORAGE_URL').'covers/default/ac9cef765e0dbf0bda625b3d1d3b446d.png';
}else{
$cur = str_replace('Ao Vivo','',$cur);
$finalCover = getDeezerCover($cur);
if (!$finalCover) {
$finalCover = getItunesCoverWithFallback($cur, $exp);
}
if (!$finalCover && isset($exp[0])) {
$finalCover = getDeezerCover($exp[0]);
}
if (!$finalCover) {
$finalCover = null;
}
}
}
}
}
return response()->json(['cover' => $finalCover]);
}
public function getCover()
{
if (Auth::check() === false) {
Auth::logout();
return redirect()->route('login');
}
$connection = 'mysql_site_' . session('serverID');
$siteData = DB::connection($connection)
->table('sites')
->where('id', '=', session('siteID'))
->first();
$siteSettings = DB::connection($connection)
->table('settings')
->where('site_id', '=', session('siteID'))
->first();
// Capa desativada nas configurações do site
if (!$siteData || ($siteSettings && $siteSettings->metadata_cover == '0')) {
return response()->json(['cover' => null]);
}
$cover = Cache::remember(
'cover:' . $siteData->stream_port,
10, // segundos — evita flood na cover-api com o polling do player
function () use ($siteData) {
try {
$response = Http::timeout(3)
->connectTimeout(2)
->get('https://cover-api.brascast.com/cover', [
'p' => $siteData->stream_port,
's' => $siteData->stream_server,
]);
if (!$response->successful()) {
return null;
}
$data = $response->json();
if (empty($data['success'])) {
return null;
}
return $data['image_url'] ?: null;
} catch (\Throwable $e) {
return null;
}
}
);
return response()->json(['cover' => $cover]);
}
/**
* Tudo o que a /radio/home mostra, numa resposta so.
*
* A tela antiga pedia seis vezes: ouvintes, estado, bloco do auto dj, bloco
* do ao vivo, faixa atual e capa. Essas seis chamadas buscavam quatro
* enderecos diferentes no servidor de streaming, e repetiam o mesmo endereco
* ate tres vezes. Medido daqui, com o servidor no Brasil, davam 3,1 s.
*
* Aqui cada endereco e buscado uma vez so e os quatro saem juntos, com
* curl_multi: o tempo passa a ser o da chamada mais lenta, e o navegador faz
* uma ida e volta em vez de seis. Com servidor noutro continente essa
* diferenca vira segundos.
*
* A informacao devolvida e exatamente a mesma que as seis rotas antigas
* entregam; o que mudou foi o transporte.
*/
public function state()
{
if (Auth::check() === false) {
Auth::logout();
return redirect()->route('login');
}
$siteData = SiteContext::current();
$stream = DB::table('streamings')->where('port', '=', $siteData->stream_port)->first();
if (! $stream) {
return response()->json(['ok' => false, 'error' => 'stream_not_found'], 404);
}
$server = DB::table('servers')->where('id', '=', $stream->server_id)->first();
$master = DB::table('settings')->where('id', '=', 1)->first();
$base = 'https://' . $server->name . '.' . env('BASE_SERVER_URL', 'brascast.com');
$icecast = 'http://' . $server->ip . ':' . $stream->port;
$alvos = [
'status' => ['url' => $icecast . '/status-json.xsl'],
'listeners' => [
'url' => $icecast . '/admin/listclients',
'headers' => ['Authorization: Basic ' . base64_encode($master->master_user . ':' . $master->master_pass)],
],
'info' => ['url' => $base . '/bras_api/data/info.php?p=' . $stream->port],
'history' => ['url' => $base . '/bras_api/data/history.php?p=' . $stream->port],
];
$respostas = $this->fetchAll($alvos);
$status = json_decode((string) $respostas['status'], false);
$info = json_decode((string) $respostas['info'], true);
$history = json_decode((string) $respostas['history'], true);
$djs = DB::table('djs')->where('port', '=', $siteData->stream_port)->where('active', '=', '1')->get();
$relays = DB::table('relays')->where('port', '=', $siteData->stream_port)->where('active', '=', '1')->count();
return response()->json([
'ok' => true,
'listeners' => $this->countListeners($respostas['listeners']),
'sources' => $this->sources($status, $djs->count(), $relays),
'now' => [
'current' => $history['current'] ?? null,
'next' => $history['next'] ?? null,
],
'autodj' => [
'codec' => ($stream->autodj_codec == 'aac' ? 'AAC+' : 'MP3')
. '(' . $stream->autodj_bitrate . 'kbps, Stereo, ' . $stream->autodj_sample . 'kHz)',
'since' => $this->broadcastTime($stream->autodj_time ?? null),
'playlist' => DB::table('playlists')->where('id', '=', $stream->current_playlist_id)->value('name'),
'status' => $info['status_autodj'] ?? null,
'history' => array_values((array) ($history['list'] ?? [])),
],
'live' => $this->liveBlock($djs, $status),
]);
}
/**
* Busca todos os enderecos ao mesmo tempo.
*
* O tempo total passa a ser o da chamada mais lenta, e nao a soma delas.
* Falha de um endereco nao derruba os outros: quem falhou volta null e a
* tela mostra o que deu para saber.
*/
private function fetchAll(array $alvos): array
{
$multi = curl_multi_init();
$handles = [];
foreach ($alvos as $chave => $alvo) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $alvo['url'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_TIMEOUT => 8,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_USERAGENT => 'BRASCASTX',
CURLOPT_HTTPHEADER => $alvo['headers'] ?? [],
]);
curl_multi_add_handle($multi, $ch);
$handles[$chave] = $ch;
}
do {
$andamento = curl_multi_exec($multi, $ativos);
if ($ativos) {
curl_multi_select($multi, 1);
}
} while ($ativos && $andamento === CURLM_OK);
$saida = [];
foreach ($handles as $chave => $ch) {
$corpo = curl_multi_getcontent($ch);
$codigo = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
$saida[$chave] = $codigo >= 200 && $codigo < 300 ? $corpo : null;
curl_multi_remove_handle($multi, $ch);
curl_close($ch);
}
curl_multi_close($multi);
return $saida;
}
/** O numero de ouvintes, do xml do Icecast. */
private function countListeners($xmlBruto): int
{
if (! $xmlBruto) {
return 0;
}
$xml = @simplexml_load_string(xml_entity_decode($xmlBruto));
return $xml ? (int) $xml->listeners : 0;
}
/**
* Quais fontes existem na tela e qual esta no ar.
*
* Mesma regra do statusInfo(): auto dj e ao vivo convivem, um no ar e o
* outro em espera; relay entra no lugar do auto dj; sem nenhum dos dois a
* tela cai em manutencao.
*/
private function sources($status, int $djs, int $relays): array
{
$autodj = 'off';
if (isset($status->icestats->source)) {
$texto = json_encode($status->icestats->source);
$primeiro = json_encode($status->icestats->source[0]->server_name ?? '');
if (stripos($texto, '/autodj') !== false || stripos($primeiro, '/autodj') !== false) {
$autodj = 'on';
}
}
$aoVivo = $djs >= 1;
$temRelay = $relays >= 1;
if ($autodj === 'off' && ! $aoVivo && ! $temRelay) {
return ['onair' => 'manu', 'autodj' => 'off', 'live' => 'off', 'relay' => 'off'];
}
$noAr = $aoVivo ? 'live' : ($temRelay ? 'relay' : 'autodj');
return [
'onair' => $noAr,
/* ligado mas em segundo plano quando o ar e de outro */
'autodj' => $autodj === 'on' ? ($noAr === 'autodj' ? 'live' : 'standby') : 'off',
'live' => $aoVivo ? ($noAr === 'live' ? 'live' : 'standby') : 'off',
'relay' => $temRelay ? ($noAr === 'relay' ? 'live' : 'standby') : 'off',
];
}
private function broadcastTime($rawTime): string
{
if (! $rawTime) {
return '--';
}
$timestamp = strtotime($rawTime);
return Cookie::get('locale', 'pt') === 'pt'
? date('d/m/Y H:i', $timestamp)
: date('Y-m-d H:i', $timestamp);
}
/** Dados do locutor no ar, quando ha um. */
private function liveBlock($djs, $status): array
{
if (! $djs->count()) {
return ['connected' => false, 'name' => null, 'ip' => null, 'since' => null, 'codec' => 'AAC+', 'bitrate' => '128'];
}
$tipos = ['audio/aacp' => 'AAC+', 'audio/mpeg' => 'MP3', 'audio/aac' => 'AAC+'];
$fonte = $status->icestats->source[0] ?? null;
return [
'connected' => true,
'name' => $djs[0]->name,
'ip' => $djs[0]->last_ip,
'since' => $djs[0]->last_login ?? null,
'codec' => $tipos[$fonte->server_type ?? ''] ?? 'AAC+',
'bitrate' => (string) ($fonte->bitrate ?? '128'),
];
}
}