diff --git a/src/admin/stream_view.php b/src/admin/stream_view.php index d2d9c983..0308a87f 100644 --- a/src/admin/stream_view.php +++ b/src/admin/stream_view.php @@ -562,7 +562,7 @@ if ($rStream['type'] == 1) { $rFPS = '--'; } - $rStreamInfoText = ""; + $rStreamInfoText = "
" . number_format($rTrack['stream_info']['bitrate'] / 1024, 0) . " Kbps
"; $rStreamInfoText .= "'; $rStreamInfoText .= '
" . number_format(intval($rTrack['stream_info']['bitrate']) / 1024, 0) . " Kbps
" . $rTrack['stream_info']['codecs']['video']['width'] . ' x ' . $rTrack['stream_info']['codecs']['video']['height'] . '' . $rTrack['stream_info']['codecs']['video']['codec_name'] . '' . $rTrack['stream_info']['codecs']['audio']['codec_name'] . '' . $rFPS . '
'; diff --git a/src/includes/CoreUtilities.php b/src/includes/CoreUtilities.php index 0818da60..fb004d4c 100644 --- a/src/includes/CoreUtilities.php +++ b/src/includes/CoreUtilities.php @@ -1471,24 +1471,32 @@ class CoreUtilities { if (substr($rSource, 0, 2) == 's:') { $rSplit = explode(':', $rSource, 3); $rServerID = intval($rSplit[1]); + $rSourcePath = $rSplit[2]; // File path if ($rServerID != SERVER_ID) { - $rSourcePath = self::$rServers[$rServerID]['api_url'] . '&action=getFile&filename=' . urlencode($rSplit[2]); - } else { - $rSourcePath = $rSplit[2]; + // File on another server - needs to be retrieved via API. + if (is_array(self::$rServers) && isset(self::$rServers[$rServerID])) { + $rSourcePath = self::$rServers[$rServerID]['api_url'] . '&action=getFile&filename=' . urlencode($rSplit[2]); + } else { + // Server not found, use local path. + $rSourcePath = $rSplit[2]; + } } } else { $rServerID = SERVER_ID; $rSourcePath = $rSource; } - if ($rServerID == SERVER_ID && $rStream['stream_info']['movie_symlink'] == 1) { + if ($rServerID == SERVER_ID && intval($rStream['stream_info']['movie_symlink']) == 1) { $rExtension = pathinfo($rSource)['extension']; - if (strlen($rExtension) != 0) { - } else { + if (strlen($rExtension) == 0) { $rExtension = 'mp4'; } + // Create symlink $rCommand = 'ln -sfn ' . escapeshellarg($rSourcePath) . ' "' . CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.' . escapeshellcmd($rExtension) . '" >/dev/null 2>/dev/null & echo $! > "' . CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.pid"'; } else { $rStream['stream_info']['transcode_attributes'] = json_decode($rStream['stream_info']['profile_options'], true); + if (!is_array($rStream['stream_info']['transcode_attributes'])) { + $rStream['stream_info']['transcode_attributes'] = array(); + } $rLogoOptions = (isset($rStream['stream_info']['transcode_attributes'][16]) && !$rLoopback ? $rStream['stream_info']['transcode_attributes'][16]['cmd'] : ''); $rGPUOptions = (isset($rStream['stream_info']['transcode_attributes']['gpu']) ? $rStream['stream_info']['transcode_attributes']['gpu']['cmd'] : ''); $rInputCodec = ''; @@ -1501,16 +1509,14 @@ class CoreUtilities { } } $rCommand = ((isset($rStream['stream_info']['transcode_attributes']['gpu']) ? self::$rFFMPEG_GPU : self::$rFFMPEG_CPU)) . ' -y -nostdin -hide_banner -loglevel ' . ((self::$rSettings['ffmpeg_warnings'] ? 'warning' : 'error')) . ' -err_detect ignore_err {GPU} -fflags +genpts -async 1 -i {STREAM_SOURCE} {LOGO} '; - if (array_key_exists('-acodec', $rStream['stream_info']['transcode_attributes'])) { - } else { + + if (!array_key_exists('-acodec', $rStream['stream_info']['transcode_attributes'])) { $rStream['stream_info']['transcode_attributes']['-acodec'] = 'copy'; } - if (array_key_exists('-vcodec', $rStream['stream_info']['transcode_attributes'])) { - } else { + if (!array_key_exists('-vcodec', $rStream['stream_info']['transcode_attributes'])) { $rStream['stream_info']['transcode_attributes']['-vcodec'] = 'copy'; } - if (!isset($rStream['stream_info']['transcode_attributes']['gpu'])) { - } else { + if (isset($rStream['stream_info']['transcode_attributes']['gpu'])) { $rCommand .= '-gpu ' . intval($rStream['stream_info']['transcode_attributes']['gpu']['device']) . ' '; } $rCommand .= implode(' ', self::parseTranscode($rStream['stream_info']['transcode_attributes'])) . ' '; diff --git a/src/includes/admin_api.php b/src/includes/admin_api.php index 670e58d2..ec356f36 100644 --- a/src/includes/admin_api.php +++ b/src/includes/admin_api.php @@ -65,7 +65,7 @@ class API { return !empty($rData['stream_display_name']) || isset($rData['review']) || isset($_FILES['m3u_file']); case 'processEpisode': - return !empty($rData['series']) && is_numeric($rData['season_num']) && is_numeric($rData['episode']); + return !empty($rData['series']) && is_numeric($rData['season_num']) && (isset($rData['multi']) || is_numeric($rData['episode'])); case 'processSeries': return !empty($rData['title']); @@ -564,7 +564,12 @@ class API { $rArray['stream_source'] = $rPlaylist; $rArray['series_no'] = intval($rData['series_no']); } else { - $rArray['stream_source'] = $rData['video_files']; + // video_files comes as a JSON string from the form, it needs to be decoded + $rVideoFiles = $rData['video_files']; + if (is_string($rVideoFiles)) { + $rVideoFiles = json_decode($rVideoFiles, true); + } + $rArray['stream_source'] = is_array($rVideoFiles) ? $rVideoFiles : []; $rArray['series_no'] = 0; } @@ -681,15 +686,13 @@ class API { } } - if (!$rReencode) { - } else { + if ($rReencode) { APIRequest(array('action' => 'stream', 'sub' => 'stop', 'stream_ids' => array($rInsertID))); self::$db->query("UPDATE `streams_servers` SET `pids_create_channel` = '[]', `cchannel_rsources` = '[]' WHERE `stream_id` = ?;", $rInsertID); CoreUtilities::queueChannel($rInsertID); } - if (!$rRestart) { - } else { + if ($rRestart) { APIRequest(array('action' => 'stream', 'sub' => 'start', 'stream_ids' => array($rInsertID))); } diff --git a/src/includes/cli/created.php b/src/includes/cli/created.php index c09d22e7..8701f8a1 100644 --- a/src/includes/cli/created.php +++ b/src/includes/cli/created.php @@ -36,56 +36,46 @@ if (posix_getpwuid(posix_geteuid())['name'] == 'xc_vm') { exec('kill -9 ' . $rCurrentPID); } } - echo 'Processing source: ' . $rSource . '...' . "\n"; $rItemPID = CoreUtilities::createChannelItem($rStreamID, $rSource); - $db->close_mysql(); - - while (CoreUtilities::isPIDRunning(SERVER_ID, $rItemPID, CoreUtilities::$rFFMPEG_CPU)) { - sleep(1); + // Only wait if a transcoding process is running. + if ($rItemPID > 0) { + while (CoreUtilities::isPIDRunning(SERVER_ID, $rItemPID, CoreUtilities::$rFFMPEG_CPU)) { + sleep(1); + } } + $db->db_connect(); + @unlink(CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.pid'); + @unlink(CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.errors'); $rServerInfo['cchannel_rsources'][] = $rSource; - - $db->db_connect(); - $db->query( - 'UPDATE `streams_servers` SET `cchannel_rsources` = ? WHERE `server_stream_id` = ?', - json_encode($rServerInfo['cchannel_rsources']), - $rServerInfo['server_stream_id'] - ); - - if (file_exists(CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.pid')) { - unlink(CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.pid'); - } - - if (file_exists(CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.errors')) { - unlink(CREATED_PATH . intval($rStreamID) . '_' . $rMD5 . '.errors'); - } + $db->query('UPDATE `streams_servers` SET `cchannel_rsources` = ? WHERE `server_stream_id` = ?', json_encode($rServerInfo['cchannel_rsources']), $rServerInfo['server_stream_id']); } - $rOutputList = ''; - foreach ($rStreamInfo['stream_source'] as $rSource) { + // Extract server and path from source. if (substr($rSource, 0, 2) == 's:') { $rSplit = explode(':', $rSource, 3); $rServerID = intval($rSplit[1]); + $rSourcePath = $rSplit[2]; } else { $rServerID = SERVER_ID; + $rSourcePath = $rSource; } - if ($rServerID == SERVER_ID && $rStreamInfo['movie_symlink'] == 1) { - $rExtension = pathinfo($rSource)['extension']; - if (strlen($rExtension) == 0) { - $rExtension = 'mp4'; + // If movie_symlink == 1 and the file is local, use the direct original path. + if ($rServerID == SERVER_ID && intval($rStreamInfo['movie_symlink']) == 1) { + if (file_exists($rSourcePath)) { + $rOutputList .= "file '" . $rSourcePath . "'" . "\n"; } } else { - $rExtension = 'ts'; - } - - if (file_exists(CREATED_PATH . $rStreamID . '_' . md5($rSource) . '.' . $rExtension)) { - $rOutputList .= "file '" . CREATED_PATH . $rStreamID . '_' . md5($rSource) . '.' . $rExtension . "'" . "\n"; + // Uses transcoded file in CREATED_PATH + $rCreatedFile = CREATED_PATH . $rStreamID . '_' . md5($rSource) . '.ts'; + if (file_exists($rCreatedFile)) { + $rOutputList .= "file '" . $rCreatedFile . "'" . "\n"; + } } } @@ -125,14 +115,7 @@ if (posix_getpwuid(posix_geteuid())['name'] == 'xc_vm') { file_put_contents(CREATED_PATH . $rStreamID . '_.info', json_encode($rReturn, JSON_UNESCAPED_UNICODE)); echo 'Completed!' . "\n"; - - $createFile = CREATED_PATH . $rStreamID . '_.create'; - if (file_exists($createFile)) { - $savedPID = intval(file_get_contents($createFile)); - if ($savedPID === getmypid()) { - unlink($createFile); - } - } + @unlink(CREATED_PATH . $rStreamID . '_.create', getmypid()); } } else { echo "Channel doesn't exist on this server." . "\n";