그누보드 게시판에 LMS 영상 게시판 만들기

· 2026-02-18 (수) 12:24:41 · 3558 · 3

1771385260_KHEVk6DNOk.webp

lms_update.skin.php
[code]
<?php
// 이 파일은 게시판 스킨 폴더 안에 위치합니다.
include_once('../../../../../common.php'); // 경로 주의: 스킨 폴더 위치에 따라 상위 이동 횟수 조절

if (!$is_member) die("ERROR:LOGIN");

$bo_table = preg_replace('/[^a-z0-9_]/i', '', $_POST['bo_table']);
$wr_id    = (int)$_POST['wr_id'];
$current  = (int)$_POST['current'];
$percent  = (int)$_POST['percent'];

if (!$bo_table || !$wr_id) die("ERROR:DATA");

// 테이블명 생성
$write_table = $g5['write_prefix'] . $bo_table;

// 진도율 100%를 넘지 않게 방어
if($percent > 100) $percent = 100;

// 업데이트 쿼리 (wr_9: 진도율, wr_10: 시청초)
// 로그인한 사용자의 글인지 확인하는 조건(mb_id)을 넣어야 타인이 내 진도를 못 바꿉니다.
$sql = " UPDATE {$write_table}
            SET wr_9 = '{$percent}',
                wr_10 = '{$current}'
          WHERE wr_id = '{$wr_id}' 
            AND mb_id = '{$member['mb_id']}' ";

if(sql_query($sql)) {
    echo "SUCCESS";
} else {
    echo "ERROR:SQL_FAIL";
}
?>
[/code]

view.php
[code]

<div class="video-container mb-3 position-relative" style="background:#000;">
    <video id="lectureVideo" width="100%" controls playsinline controlsList="nodownload" poster="<?php echo $board_skin_url; ?>/img/video_poster.jpg">
        <source src="<?php echo $view['link'][1];?>" type="video/mp4">
        브라우저가 video 태그를 지원하지 않습니다.
    </video>
</div>

<div class="alert alert-light border border-primary-subtle shadow-sm">
    <div class="d-flex justify-content-between align-items-center mb-1">
        <span class="fw-bold"><i class="fa fa-play-circle text-primary"></i> 학습 진행 상황</span>
        <span class="badge bg-primary"><span id="progressPercent"><?php echo (int)$write['wr_9']; ?></span>% 완료</span>
    </div>
    <div class="progress" style="height: 10px; background-color: #e9ecef;">
        <div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated" 
             role="progressbar" 
             style="width: <?php echo (int)$write['wr_9']; ?>%; transition: width 0.3s ease;">
        </div>
    </div>
</div>

<script>
$(function() {
    const video = document.getElementById('lectureVideo');
    const UPDATE_URL = "<?php echo $board_skin_url; ?>/lms_update.skin.php";
    
    // 초기 설정값
    const conf = {
        bo_table: "<?php echo $bo_table; ?>",
        wr_id: "<?php echo $wr_id; ?>",
        lastSavedTime: <?php echo (int)$write['wr_10']; ?>,
        maxPercent: <?php echo (int)$write['wr_9']; ?>
    };

    let trackedMaxTime = conf.lastSavedTime; // 시청한 최대 지점 (초단위)
    let isInitialized = false;

    // 1. 영상 로드 시 이어보기 및 최대 지점 설정
    video.addEventListener('loadedmetadata', function() {
        if (!isInitialized) {
            if (conf.lastSavedTime > 5) {
                if(confirm("이전에 시청하던 지점부터 이어서 보시겠습니까?")) {
                    video.currentTime = conf.lastSavedTime;
                    trackedMaxTime = conf.lastSavedTime;
                }
            }
            isInitialized = true;
        }
    });

    // 2. 앞으로 건너뛰기(Seeking) 제한 로직
    video.addEventListener('seeking', function() {
        if (video.currentTime > trackedMaxTime + 1) { // 1초 정도의 오차 허용
            alert("학습하지 않은 구간으로는 건너뛸 수 없습니다.");
            video.currentTime = trackedMaxTime;
        }
    });

    // 3. 시간 업데이트 시 최대 시청 지점 갱신 및 진도 계산
    video.addEventListener('timeupdate', function() {
        if (!video.seeking) {
            if (video.currentTime > trackedMaxTime) {
                trackedMaxTime = video.currentTime;
            }
        }

        const current = Math.floor(video.currentTime);
        const duration = Math.floor(video.duration);
        
        if (duration > 0) {
            let livePercent = Math.floor((trackedMaxTime / duration) * 100);
            if (livePercent > conf.maxPercent) {
                conf.maxPercent = livePercent > 100 ? 100 : livePercent;
                $('#progressPercent').text(conf.maxPercent);
                $('#progressBar').css('width', conf.maxPercent + '%');
            }
        }
    });

    // 4. 데이터 전송 함수 (AJAX 및 Beacon)
    function sendLmsData(isBeacon = false) {
        const current = Math.floor(video.currentTime);
        const percent = conf.maxPercent;

        if (isBeacon) {
            // 페이지 이탈 시 비동기 전송 보장
            const formData = new FormData();
            formData.append('bo_table', conf.bo_table);
            formData.append('wr_id', conf.wr_id);
            formData.append('current', current);
            formData.append('percent', percent);
            navigator.sendBeacon(UPDATE_URL, formData);
        } else {
            // 일반 자동 저장
            $.ajax({
                url: UPDATE_URL,
                type: 'POST',
                data: {
                    bo_table: conf.bo_table,
                    wr_id: conf.wr_id,
                    current: current,
                    percent: percent
                },
                dataType: 'json'
            });
        }
    }

    // 10초마다 자동 저장
    const saveInterval = setInterval(function() {
        if (!video.paused) sendLmsData();
    }, 10000);

    // 페이지 이탈 시 (창 닫기, 뒤로가기 등) 즉시 저장
    window.addEventListener('visibilitychange', function() {
        if (document.visibilityState === 'hidden') {
            sendLmsData(true);
        }
    });
});
</script>
[/code]

간단하게 영상도 마지막 본 상태에서 재생도 가능합니다.

기본틀이니 각자 영상 진행율 저장하는 DB 만들고 연동하면 될듯 싶네요
100% 수료증 발급 페이지 만들고 하면 응 나름 
영상은 네이버 영상 무료로 업로드 가능합니다 그쪽을 이용하시면될듯싶습니다.

ex) https://tv.naver.com/embed/코드번호?autoPlay=true 영상 업로드후 LMS 영상 재생해주는 홈페이지가 몇군데 있습니다.

첨부파일

view_comment.skin.php (10.6 KB) 2회 2026-02-19 17:26
list.skin.php (11.7 KB) 1회 2026-02-19 17:26
lms_update.skin.php (1.2 KB) 0회 2026-02-19 17:26
5명이 반응했습니다
|

댓글 3개

좋아요. 감사 합니다.

고금 스킬 알려주셔서 감사합니다

학습 진행 상황과 봤던 시점부터 다시보기 기능 잘 이용하도록 하겠습니다

감사합니다.
댓글을 작성하시려면 로그인이 필요합니다.

그누보드5 팁자료실

2,788건
+
제목 글쓴이 날짜 조회
03-07 조회 5,118
03-06 조회 4,409
03-06 조회 4,483
03-05 조회 4,727
03-02 조회 4,402
02-19 조회 5,556
02-19 조회 6,058
02-18 조회 3,559
02-06 조회 5,884
02-02 조회 5,026
01-31 조회 3,779
01-25 조회 3,856
01-22 조회 3,912
01-19 조회 3,662
01-18 조회 3,761
01-17 조회 3,686
01-15 조회 4,272
01-14 조회 4,321
01-08 조회 3,733
01-07 조회 3,699
01-02 조회 3,945
25-12-31 조회 5,112
25-12-30 조회 3,554
25-12-29 조회 3,925
25-12-20 조회 3,876
25-12-17 조회 3,555
25-12-10 조회 3,618
25-12-10 조회 3,734
25-12-07 조회 3,601
25-12-07 조회 5,255