Skip to content

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

Open
@arifje

Description

@arifje

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions