htmlcss.fr Des tutos ou tutoriels Wordpress, html, php ou javascript.

Ajouter des vidéos Youtube ou Vimeo dans la médiatheque de wordpress

A

Pour un client, j’avais besoin d’un carrousel avec des images et des vidéos.
J’aime bien le champ galerie d’ACF et je ne voulais pas faire un bricolage avec un répéteur.
Alors j’ai cherché comment je pouvez ajouter une vidéo Youtube ou Vimeo dans la médiathèque de WordPress.
Le principe de base est assez simple:

  • je récupère dynamiquement la miniature de la vidéo et je l’ajoute dans la médiathèque comme une image simple,
  • je rajoute des métadonnées pour savoir que « c’est une vidéo » et avec quelques informations utiles
  • je rajoute les meta données dans le tableau que me renvoi ACF si « c’est une vidéo »

Donc en front, vous n’avez qu’a examiner le tableau du média et toutes les données seront là.

Cela vous permet d’ajouter une vidéo / iframe via les champs image d’ACF, et ça c’est cool.

Il faut juste ajouter la classe suivante dans le functions.php de votre thème et vous aurez une nouvelle entrée dans les médias : « ✚ Vidéo externe ».

Ca ressemble à ça :

Et en front, lorsque vous ajoutez une « vidéo » dans un champs ACF ( galerie ou image ou autre ), les données supplémentaires sont ajoutées, par exemple:

[0] => Array (
    [ID] => 95
    [id] => 95
    [title] => Patrik Kleemola plays Fernando Sor Etude 22 op. 60
    [filename] => patrik_kleemola_plays_fernando_sor_etude_22_op_60-3.jpg
    [filesize] => 151682
    [url] => http://dev.wpbase.fr/wp-content/uploads/2022/06/patrik_kleemola_plays_fernando_sor_etude_22_op_60-3.jpg
    [link] => http://dev.wpbase.fr/patrik-kleemola-plays-fernando-sor-etude-22-op-60/
    [alt] => 
    [author] => 1
    [description] => 
     => 
    [name] => patrik-kleemola-plays-fernando-sor-etude-22-op-60
    [status] => inherit
    [uploaded_to] => 0
    [date] => 2022-06-28 11:36:18
    [modified] => 2022-06-28 11:36:18
    [menu_order] => 0
    [mime_type] => image/jpeg
    [type] => image
    [subtype] => jpeg
    [icon] => http://dev.wpbase.fr/wp-includes/images/media/default.png
    [width] => 1280
    [height] => 720
    [sizes] => Array
        (
            [thumbnail] => http://dev.wpbase.fr/wp-content/uploads/2022/06/patrik_kleemola_plays_fernando_sor_etude_22_op_60-3-150x150.jpg
            ...
        )

    [externalvideo] => 1
    [video_platform] => youtube
    [video_id] => Zp_rlIaeLHQ
    [video_embed_url] => https://www.youtube-nocookie.com/embed/Zp_rlIaeLHQ?rel=0&showinfo=0
    [iframe] => <iframe src="https://www.youtube-nocookie.com/embed/Zp_rlIaeLHQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="Patrik Kleemola plays Fernando Sor Etude 22 op. 60"></iframe>
)
<?php
// ajouter des vuideo Youtube dans la media Library
class ExternalVideoToMadiaLibrary {
  private $requete_body;

  function __construct()
  {
    add_action('admin_menu', [$this,'add_menu_position'],90);
    add_filter('acf/load_attachment',  [$this, 'add_metadata_to_front'], 10, 3);
  }

  public function add_menu_position()
  {
    if (isset($_POST['add_yt_video'])) {
      //securité : on donne un faux messsage d'erreur qui ne corespond à rien pour faire chier un improbable hacker
      if (!wp_verify_nonce($_POST['nonce_ytvideo'], 'token_ytvideo')) {die('Error at line 8589: undefined property of null');}
      $this->insert();
    }
    add_submenu_page(
    'upload.php',
    'Ajouter une vidéo externe',
    '✚ Vidéo externe',
    'edit_posts',
    'add_video_medialibrary',
    [$this, 'render_import_page']);
  }

  public function render_import_page()
  {
    ?>
    <div>
      <h1>Ajouter une vidéo Youtube</h1>
      <p>Vous pouvez ajouter une vidéo Youtube ou Vimeo directement dans la médiathèque. Pour cela Vous devez renseigner l ID de la vidéo.</p>
      <p>L`ID de la vidéo est la derniére partie de l URL. Par exemple pour Youtube : <br>
      https://www.youtube.com/watch?v=<b><u>Zp_rlIaeLHQ</u></b><br>

      Et pour Vimeo<br>
      https://vimeo.com/<b><u>217624589</u></b>
      </p>

      <form method="post" action="">
      <table class="form-table">
        <tbody>
          <tr>
            <th scope="row">
              <label>Plateforme de la vidéo</label>
            </th>
            <td>
              <input id="youtube" type="radio" name="plateform" value="youtube" required/><label for="youtube"><b>Youtube</b></label><br>
              <input id="vimeo" type="radio" name="plateform" value="vimeo" required/><label for="vimeo"><b>Vimeo</b></label>
            </td>
          </tr>
          <tr>
            <th scope="row">
              <label for="video_id">ID de la vidéo</label>
            </th>
            <td>
              <input name="video_id" type="text" id="video_id" value="" class="regular-text" required>
            </td>
          </tr>
          <tr>
            <th scope="row">
              <label for="video_caption">Legende <small><i>(facultatif)</i></small></label>
            </th>
            <td>
              <textarea name="video_caption" id="video_caption" class="large-text" style="width:25em;" rows="3"></textarea>
            </td>
          </tr>
          <tr>
            <th scope="row">
              <label for="video_description">Description <small><i>(facultatif)</i></small></label>
            </th>
            <td>
              <textarea name="video_description" id="video_description" class="large-text" style="width:25em;" rows="3"></textarea>
            </td>
          </tr>
          <tr>
            <th scope="row">
              <input type="hidden" name="nonce_ytvideo" value="<?= wp_create_nonce('token_ytvideo'); ?>" >
              <input type="submit" name="add_yt_video" class="button-primary autowidth" value="Ajouter">
            </th>
            <td>
              &nbsp;
            </td>
          </tr>
        </tbody>
      </table>
      </form>

    </div>
    <?php
  }
  ///////////////////////
  //Youtube
  ///////////////////////
  private function insert()
  {
    // 0. vars
    $video_id = $_POST['video_id'];
    $video_existe = false;
    $thumbnail_url = false;
    $thumbnail_array = false;
    $is_youtube = false;
    if($_POST['plateform'] === "youtube") {
      $is_youtube = true;
    }

    if($is_youtube) {
      $theURL = "https://www.youtube-nocookie.com/oembed?url=http://www.youtube.com/watch?v=$video_id&format=json";
    }else{
      $theURL ="http://vimeo.com/api/v2/video/$video_id.json";
    }

    // 1. check si la video exist
    $request = wp_remote_get($theURL);
    if($request['response']['code'] === 200) {
      $video_existe = true;
      $request_body = $this->request_body = json_decode(wp_remote_retrieve_body($request));
    }else{
      new AdminNotice('error', '<p>L\'ID de la vidéo ne semble pas valide. Erreur de copier/coller?</p>');
    }

    // 2. Recupe l'url de la thumbnail
    if($video_existe) {
      if($is_youtube) {
        $thumbnail_url = $this->get_youtube_thumbnail($video_id);
      }else{
        $thumbnail_url = $request_body[0]->thumbnail_large.'.jpg';
      }
    }

    //3. DL the thumbnail
    if($video_existe && $thumbnail_url) {
      require_once ABSPATH . 'wp-admin/includes/file.php';
      require_once ABSPATH . 'wp-admin/includes/image.php';
      require_once ABSPATH . 'wp-admin/includes/media.php';
      $tmp = download_url( $thumbnail_url );
      $thumbnail_array = [
        'name' => basename( $thumbnail_url ),
        'tmp_name' => $tmp
      ];

      // Check for download errors, if there are error unlink the temp file name
      if ( is_wp_error( $tmp ) ) {
        @unlink( $thumbnail_array[ 'tmp_name' ] );
        new AdminNotice('error', '<p>Erreur de téléchargement de la miniature.<br>'.var_dump($tmp).'</p>');
        // return $tmp;
      }
    }else{
      new AdminNotice('error', '<p>Pas de miniature disponible. Pas d\'image.</p>');
    }

    //4. Insert the attachment.
    if($video_existe && $thumbnail_url && $thumbnail_array) {
      add_filter( 'wp_handle_sideload_prefilter', array( $this, 'change_image_name' ) );
      $attach_id = media_handle_sideload( $thumbnail_array, 0 );

      if ( is_wp_error( $attach_id ) ) {
        @unlink( $thumbnail_array[ 'tmp_name' ] );
        new AdminNotice('error', '<p>Erreur Lors de l\'ajout en base de donnée.<br>'.var_dump($attach_id).'</p>');
      }else{
        //5. add meta data
        $description = sanitize_textarea_field($_POST['video_description']);
        if(empty($description) && !$is_youtube) {
          $description = $request_body[0]->description;
        }

        $pdatas = array(
          'ID'              => $attach_id,
          'post_title'      => $is_youtube ? $request_body->title : $request_body[0]->title,
          'post_name'       => $is_youtube ? $request_body->title : $request_body[0]->title,
          'post_excerpt'    => sanitize_textarea_field($_POST['video_caption']), // caption
          'post_content'    => $description,
        );
        wp_update_post( $pdatas );

        $mdatas = wp_get_attachment_metadata($attach_id);
        $mdatas['externalvideo'] = true;
        $mdatas['video_platform'] = $is_youtube ? 'youtube' : 'vimeo';
        $mdatas['video_id'] = $is_youtube ? $video_id : $request_body[0]->id;
        $mdatas['video_embed_url'] = $is_youtube ?
          'https://www.youtube-nocookie.com/embed/'.$video_id.'?rel=0&amp;showinfo=0'
          :
          'https://player.vimeo.com/video/'.$video_id.'?h=f49596bc66&dnt=true';
        $mdatas['iframe'] = $is_youtube ?
          //width="'.$request_body->width.'" height="'.$request_body->height.'"
          '<iframe src="https://www.youtube-nocookie.com/embed/'.$video_id.'?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="'.$request_body->title.'"></iframe>'
          :
          // width="'.$request_body[0]->width.'" height="'.$request_body[0]->height.'"
          '<iframe src="https://player.vimeo.com/video/'.$video_id.'?h=f49596bc66&dnt=true" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen title="'.$request_body[0]->title.'"></iframe>';
        wp_update_attachment_metadata( $attach_id, $mdatas );

        new AdminNotice('success', '<p>La vidéo est ajoutée.Vous pouvez la retourver dans la médiathèque.</p>');
      }
    }else{
      new AdminNotice('error', '<p>La vidéo n\'a pas été ajoutée.</p>');
    }
  }

  private function get_youtube_thumbnail($ytid)
  {
    $tab_thumbnail = [
      //https://img.youtube.com/ -> Alt url
      'https://i.ytimg.com/vi/'.$ytid.'/maxresdefault.jpg',
      'https://i.ytimg.com/vi/'.$ytid.'/hqdefault.jpg',
      'https://i.ytimg.com/vi/'.$ytid.'/mqdefault.jpg',
      'https://i.ytimg.com/vi/'.$ytid.'/sddefault.jpg',
      'https://i.ytimg.com/vi/'.$ytid.'/default.jpg',
    ];

    foreach ($tab_thumbnail as $url) {
      $request = wp_remote_get($url);
      if($request['response']['code'] === 200){
        return $url;
      }
    }
    // if no picture avaliable
    return false;
  }

  public function change_image_name($file)
  {
    if($_POST['plateform'] === "youtube") {
      $path_parts = pathinfo($file['name']);
      $file['name'] = Utils::cleanstr($this->request_body->title).'.'.$path_parts['extension'];
    }else{
      $file['name'] = Utils::cleanstr($this->request_body[0]->title).'.jpg';
    }
    return $file;
  }

  // Add to ACF new metadatas
  public function add_metadata_to_front( $front_obj, $wp_post, $metadatas ) {
    if($metadatas['externalvideo']) {
      $front_obj['externalvideo'] = true;
      // // $front_obj['width'] = $metadatas['width'];
      // // $front_obj['height'] = $metadatas['height'];
      // // $front_obj['file'] = $metadatas['file'];
      // // $front_obj['sizes'] = $metadatas['sizes'];
      $front_obj['video_platform'] = $metadatas['video_platform'];
      $front_obj['video_id'] = $metadatas['video_id'];
      $front_obj['video_embed_url'] = $metadatas['video_embed_url'];
      $front_obj['iframe'] = $metadatas['iframe'];
    }
    return $front_obj;
  }
}
$externalVideoToMadiaLibrary = new ExternalVideoToMadiaLibrary();
htmlcss.fr Des tutos ou tutoriels Wordpress, html, php ou javascript.

François Riant

Je m’appelle François Riant. Je travail dans les métiers du web depuis 2006. Mon expérience m’a amené à changer plusieurs fois de technologie.

Aujourd’hui je cherche à partager mon expérience et j’y trouve du de plaisir. Je travail actuellement chez W2P Digital.
Je ne prends donc pas de mission en freelance.

Si vous avez une remarque ou une question; vous pouvez me joindre sur francois.riant@gmail.com