Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add possibility to check for encoded videos via CURL/HTTP instead of local paths #66

Open
arifje opened this issue Mar 16, 2023 · 0 comments

Comments

@arifje
Copy link
Contributor

arifje commented Mar 16, 2023

Currently all functions that are checking if an encoded version of the video/gif/audio exists, are looking for a local path, like "/content/video/encoded/video.mp4". While that might work fine when your data is on the same server, this is not te case when your content is hosted on a remote server or CDN.

In our case that path is pointing to a NFS share and NFS shares are a risk due to connection issues. Also, we have multiple backends (web) and we need to create a NFS share on each of these clients to keep this plugin working and detecting the encoded files. When the NFS server doesn't respond, all webservers freeze.

A better approach to my opinion would be to do this check with a simple CURL/HTTP request. I dirty hacked our version to test it, and it seem to work fine;

   public function getVideoUrl(string|Asset $filePath, array $videoOptions, bool $generate = true, array $encodingOptions = []): string
    {
        $result = '';
        $settings = Transcoder::$plugin->getSettings();
        $subfolder = '';
        $devMode = Craft::$app->config->getGeneral()->devMode;
         
        // Sub folder check
        if (is_object($filePath) && ($filePath instanceof Asset) && $settings['createSubfolders']) {          
            $subfolder = $filePath->folderPath;
        } else {        
            // Grab segment from URL
            $segments = explode("/", $filePath);
            $subfolder = $segments[count($segments)-2] . '/';
        }
        
        // Video options
        $videoOptions = $this->coalesceOptions('defaultVideoOptions', $videoOptions);
    
        // Get the video encoder presets to use
        $videoEncoders = $settings['videoEncoders'];
        $thisEncoder = $videoEncoders[$videoOptions['videoEncoder']];
        $videoOptions['fileSuffix'] = $thisEncoder['fileSuffix'];
                    
        // Destination video file
        $destVideoFile = $this->getFilename($filePath, $videoOptions);
                   
        // Generate video 
        if($generate) {
  
            // Encoded video URL
            $url = $settings['transcoderUrls']['video'] . $subfolder ?? $settings['transcoderUrls']['default'];
            $encodedUrl = Craft::parseEnv($url) . $destVideoFile;                    
          
            // Remote url is passed, check if it exists
            if (!is_object($filePath) && filter_var($filePath, FILTER_VALIDATE_URL)) {
                                
                // curl request
                $ch = curl_init($encodedUrl);
                curl_setopt($ch, CURLOPT_NOBODY, true);
                curl_exec($ch);
                $retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);

                if($retcode=="200") {
                    return $encodedUrl;                      
                }         
            } 

         ....

        // Don't generate the video, check for existing encoded video, show original if there's not an encoded video            
        } else {
  
            // Encoded video URL
            $url = $settings['transcoderUrls']['video'] . $subfolder ?? $settings['transcoderUrls']['default'];
            $encodedUrl = Craft::parseEnv($url) . $destVideoFile;
            
            // Validator  
            $validator = new UrlValidator();
            $error = '';
                        
            if ($validator->validate($encodedUrl, $error)) {
    
                // curl request
                $ch = curl_init($encodedUrl);
                curl_setopt($ch, CURLOPT_NOBODY, true);
                curl_exec($ch);
                $retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);
                                
                if($retcode=="200") {
                                        
                    $result = $encodedUrl;
                                        
                } else {
                    
                    if($devMode) {
                        echo "<div class='uk-alert'>";
                        echo "<div class='uk-padding-small'>Can't find remote encoded URL:<br><br>$encodedUrl <br><br>Showing original video asset</div>";
                        echo "</div>";                        
                    }
                    
                    $result = "";
                }
            }
        }

Would be awesome if this could be integrated as an option/setting preference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant