dimsemenov / PhotoSwipe

JavaScript image gallery for mobile and desktop, modular, framework independent
http://photoswipe.com
MIT License
24.18k stars 3.31k forks source link

How to fetch a data-photodata attrubute for an mp4 video? #2084

Open acwolff opened 9 months ago

acwolff commented 9 months ago

I have a data-photodata attribute for fetching metadata of a picture and video:

<div class="pswp-gallery pswp-gallery thumbs" id="gallery">

<a href= "slides/151004-141050_Vasse.jpg" data-pswp-width="1920" data-pswp-height="965"
data-photodata= 'Exp. date: 2015:10:04 14:10:50<br> Camera: SONY NEX-6<br> Exposure: 1/200s f/8.0 ISO-100<br> Focal length: 37mm<br> Metering mode: Center weighted average<br> Exposure Program: Aperture priority<br> Flash: no<br> WB: Daylight<br> Resolution: 4912x2468<br> File size: 6.89  MB <br>Copyright ©  André Wolff<br> Author: André Wolff'
data-cropped="true" data-caption='Sony NEX-6 camera,  Light source: Daylight.<br>'>
<div class="box" >
<img   src="thumbs/151004-141050_Vasse.jpg"width="160" height="80" alt="Sony NEX-6 camera,  Light source: Daylight." title="Sony NEX-6 camera,  Light source: Daylight."  ><br>
<div class="thumbText"><strong>Image with EXIF info</strong><br></div>
</div>
</a>

<a href= "slides/IMG_0877.mp4" data-pswp-is-video="true" data-pswp-is-poster="slides/IMG_0877.jpg" data-pswp-width="608" data-pswp-height="1080"
data-photodata= 'Exp. date: Mon May 06 11:41:09 +02:00 2013<br> Resolution: 1080x1920<br> File size: 28.01  MB <br>'
data-cropped="true" data-caption='iPhone 5 MOV file in portrait format<br>'>
<div class="box video" >
<img src="slides/IMG_0877.jpg" class="video" width="67" height="120" alt="iPhone 5 MOV file in portrait format" title="iPhone 5 MOV file in portrait format"  ><br>
<div class="thumbText"><strong>iPhone movie in portrait mode</strong><br></div>
  <span class="video-icon">
      <img src="res/video-icon-s.svg" alt="Video">
  </span>
</div>
</a>

I use next code to show a button to display these metadata:

function checkExifBtn() {
    let photodata=false;
    try {
      photodata = lightbox.pswp.currSlide.data.element.getAttribute('data-photodata');
    }
    catch(err) {
          photodata=false ;
    } 
    const x = document.querySelector('.pswp__button--exifButton');
    if (!photodata) {
        x.style.display = "none";
        strPhotodata="";
    } else {
        x.style.display = "block";
        strPhotodata = photodata;
    }
}

This works correctly for an image, but not for a video, see the first 2 slides of this album: https://andrewolff.jalbum.net/PhotoSwipeVideoTest/

My question is why is lightbox.pswp.currSlide.data.element.getAttribute('data-photodata') not showing the metadata of an mp4 video?

dimsemenov commented 9 months ago

Your lightbox.pswp.currSlide.data for the video slide is just:

{html: '<video controls  poster="slides/IMG_0877.jpg"><sou…t/slides/IMG_0877.mp4" type="video/mp4"> </video>'}

I'm not sure how do you generate it, but you can store either a reference to the element or contents of data-photodata itself.

acwolff commented 9 months ago

@dimsemenov I generate that in the 'itemData' event:

   lightbox.on('itemData', (e) => {
       const element = e.itemData.element;
       if (element  && element.dataset.pswpIsVideo) {
         const videoURL = element.href;
         const imgPoster= element.dataset.pswpIsPoster;
         e.itemData = {
           html: `<video controls  poster="${imgPoster}"><source src="${videoURL}" type="video/mp4"> </video>`
         };
       }

But that is a rather complicated way to handle videos.

I still hope that you develop a video plugin!

dimsemenov commented 9 months ago

you can do something like:

if (element  && element.dataset.pswpIsVideo) {
  const videoURL = element.href;
  const imgPoster= element.dataset.pswpIsPoster;
  e.itemData = {
    html: `<video controls  poster="${imgPoster}"><source src="${videoURL}" type="video/mp4"> </video>`,
    photodata: element.dataset.photodata,
  };
}

and then access it via pswp.currSlide.data.photodata

acwolff commented 9 months ago

Yes that solves the problem, thanks!

acwolff commented 9 months ago

@dimsemenov I wonder if there is not a simular way to solve this Dynamic caption issue: https://github.com/dimsemenov/photoswipe-dynamic-caption-plugin/issues/1

If I use the dynamic caption plugin in this album, videos do not show a caption with this code:

const captionPlugin = new PhotoSwipeDynamicCaption(lightbox, {
        type:  'below',
        mobileLayoutBreakpoint: 0, 
        captionContent: (slide) => {
          try {
                return slide.data.element.dataset.caption;
            }
            catch(err) 
              return null; //'',   false or null;
            }

        }
    }); 
So I tried this:
        lightbox.on('itemData', (e) => {
       const element = e.itemData.element;
       if (element  && element.dataset.pswpIsVideo) {
         const videoURL = element.href;
         const imgPoster= element.dataset.pswpIsPoster;
         e.itemData = {
           html: `<video controls  poster="${imgPoster}"><source src="${videoURL}" type="video/mp4"> </video>`,
           photodata: element.dataset.photodata,
           caption: element.dataset.caption,
         };
       }
   And changed the PhotoSwipeDynamicCaption:

 const captionPlugin = new PhotoSwipeDynamicCaption(lightbox, {
    type:  'below',
    mobileLayoutBreakpoint: 0, 
    captionContent: (slide) => {
      try {
            return slide.data.element.dataset.caption;
        }
        catch(err) {
          return  pswp.currSlide.data.caption;
        }

    }
}); 

But that does not solve the video caption problem.

What should I change to solve also this caption problem?
acwolff commented 9 months ago

ChatGPT advised to use this code:

`const captionPlugin = new PhotoSwipeDynamicCaption(lightbox, { type: 'below', mobileLayoutBreakpoint: 0, captionContent: (slide) => { try { // Check if the current slide is a video const isVideo = slide.data.element && slide.data.element.dataset.pswpIsVideo;

        if (isVideo) {
            // Log video caption
            console.log('Video Caption:', slide.data.caption);
            return slide.data.caption;
        } else {
            // Check if slide.data.element is defined
            if (slide.data.element) {
                // Log image caption
                console.log('Image Caption:', slide.data.element.dataset.caption);
                // Return image caption or fallback to the default caption
                return slide.data.element.dataset.caption || pswp.currSlide.data.caption;
            } else {
                // Log a message if slide.data.element is undefined
                console.warn('Image element is undefined.');
                return pswp.currSlide.data.caption;
            }
        }
    } catch (err) {
        // Log any errors
        console.error('Error in captionContent:', err);
        return pswp.currSlide.data.caption;
    }
}

}); ` But that does not solve the problem as you see in my test album https://andrewolff.jalbum.net/PhotoSwipeVideoTest/

If I click on the 2nd thumbnail, no caption is displayed and the console show this:

image