본문 바로가기
Project/축구모임 홈페이지개발

[축구모임 홈페이지개발] 06/20 개발일지 Node.js / video 탭 오류 수정 및 성능 향상

by 한33 2024. 6. 21.

기존에 유튜브에서 영상을 불러와 띄우는 형식으로 반복되는 주소를 제외한 고유의 주소를 저장시켜서 띄우는 방식으로

 

video 탭을 구현했었다.

 

 

근데 영상이 쌓이면서 로딩 시간이 길어지기 시작했다.

 

그래서 더보기 버튼을 만들고, 우선은 3개의 영상 정도만 띄운 다음 더 보기 버튼을 누를 시에 나머지 영상들을 볼 수

 

있도록 수정하려한다.

 

나는 처음에는 그냥 이것도 display: none ; 같은 특성을 이용해서 보이지만 않게 하고 진행하면 될까? 라는 생각을 했는데

 

그럼 보이지만 않을 뿐 데이터를 가져오는 건 동일하기 때문에 속도적인 부분에서 이점이 없겠다는 생각을 했고,

 

기존에는 3개만 서버로부터 가져오게 하고, 이후에 더 보기 버튼을 누를 시에 json 형식으로 서버에 전송을 해서

 

나머지를 더 가져오는 식으로 접근하려했다.

 

우선 기존 /video 엔드포인트에서는 limit(3) 을 넣어서 3개만 가져오게 했고,

 

서버에 /load-more-videos 엔드포인트를 추가한다.

 

app.get('/video', this.isLoggedIn, async (req, res) => {
  let URL3 = await db.collection('youtubeURL').find().sort({ _id: -1 }).limit(3).toArray();

  res.render('video.ejs', { URL3:URL3 });
});

app.get('/load-more-videos', this.isLoggedIn, async (req, res) => {
  try {
    // DB에서 추가적인 비디오 데이터를 가져옴
    const newVideos = await db.collection('youtubeURL').find().sort({ _id: -1 }).skip(3).toArray();
    res.json(newVideos); // JSON 형식으로 클라이언트에 응답
  } catch (error) {
    console.error('Error loading more videos:', error);
    res.status(500).send('Failed to load more videos');
  }
});

 

/load-more-videos 엔드포인트에서는 3개를 스킵한 나머지 값들을 newVideos 변수에 저장해서 json 형식으로 클라이언트

에 전달했다.

 

        async function loadMoreVideos() {
            var 유저 = '<%=유저.username%>'

            const response = await fetch('/load-more-videos'); // 서버에 요청을 보냄
            const newVideos = await response.json(); // JSON 형식의 응답을 받아옴
 
            // 받아온 데이터를 기존 비디오 목록에 추가
            const videoContainer = document.querySelector('.story-video-moreview');
            newVideos.forEach(video => {
                const div = document.createElement('div');
                div.className = 'story-photo-area';
                div.innerHTML = `
        ${video.URL}" frameborder="0" allowfullscreen></iframe>
        ${유저 === '관리자' ? `<div><a style="color: white;" href="#" onclick="confirmDeleteVideo(event)" data-video-id="${video._id}">삭제</a></div>` : ''}
      `;                videoContainer.insertBefore(div, document.querySelector('.story-video-moreviewbt'));
            });
        }

 

삭제 버튼을 위해서 이전 introduce 탭에서 배웠던 유저 함수를 <%%> 형식에서 script 에서 사용가능한 꼴로 바꿔주고,

 

받아온 나머지 영상 데이터들을 추가해주었다.

 


 

최근 계속 발견된 에러 중 하나는, 이상하게 컴퓨터로 유튜브 링크를 등록하면  video 탭에 잘 저장이 되는데,

 

모바일 환경에서 등록하면  저장이 잘 안된다는 것이다.

 

실험을 해보니 모바일 환경과 pc 환경에서 뜨는 유튜브 링크 형식이 달랐다.

 

같은 영상이어도 모바일 환경에서는

 

https://youtu.be/thEOPgSo0CA?si=dOvIOu-FEZYeGn-c

 

이런 식으로 떴고,

 

PC 환경에서는

 

https://www.youtube.com/watch?v=thEOPgSo0CA

 

이런 식으로 떴다.

 

나는 PC 기준으로 코딩을 했기 때문에 영상마다 다른 값이 v= 뒤 마지막 코드가 다른 걸 파악해 그 뒤에 문자들을 

 

데이터베이스에 저장시키고 불러와서 기능을 구현했었다.

 

하지만 모바일로 저장할 때도 기능을 구현하게 해야했다.

 

우선 모바일에서 공유 후 등록 시 URL 스타일이 다르기 때문에 이를 먼저 분석하고자 다른 링크들을 가져왔다.

 

https://youtu.be/zv7Hslm3eE4?si=ItkvOaBs8XQoIzMG

 

https://youtu.be/SdLKLS4CZQI?si=N8MHmdo11zTr8hx4

 

보니까 

https://youtu.be/ + SdLKLS4CZQI + ?si=N8MHmdo11zTr8hx4

 

이런 형식이고,

 

우리는 가운데 문자열을 저장시키면 될 거다.

 

    function UploadYoutube() {
  var fullURL = document.getElementById('inputYoutubeURL').value;
  var videoId;

  if (fullURL.startsWith('https://www.youtube.com/watch?v=')) {
    var videoIdStartIndex = fullURL.indexOf('v=') + 2;
    videoId = fullURL.substring(videoIdStartIndex);
  } else if (fullURL.startsWith('https://youtu.be/')) {
    var videoIdStartIndex = fullURL.indexOf('.be/') + 4;
    var videoIdEndIndex = fullURL.indexOf('?') !== -1 ? fullURL.indexOf('?') : fullURL.length;
    videoId = fullURL.substring(videoIdStartIndex, videoIdEndIndex);
  }

  var modifiedVideoId = videoId.replace(/&/g, '?');
  location.href = `/UploadURL?URL=${encodeURIComponent(modifiedVideoId)}`;
}

 

위와 같이 https://www.youtube.com/watch?v= 로 시작하는 경우에는 v= 이후의 문자를 보냈고

 

https://youtu.be/ 로 시작하는 경우에는 ? 가 나올 때 까지의 문자를 저장시켜서 보냈다.

 

이렇게하니 모바일 환경, PC 환경 상관없이 정상적으로 영상이 등록된 것을 확인할 수 있었다.  굿!

 


 

추가로 발견한 부분이 더보기 버튼이 계속 남아있어서 클릭을 계속 하면 나머지 영상들이 계속 아래로 쌓였다.

 

그래서 나는 더보기 버튼이 한 번 눌리면 사라지게 하길 원했고.

 

<div class="story-video-moreviewbt" onclick="loadMoreVideos(this)">
                            더 보기
                        </div>

 

async function loadMoreVideos(button) {
            var 유저 = '<%=유저.username%>'
            button.style.display = 'none';

 

다음처럼 코드를 수정해주었다.