본문으로 건너뛰기

플레이어 제어 스크립트 (VG Controller)

개요

플레이어 제어 스크립트(VG Controller)는 고객사의 웹사이트에 iframe으로 삽입된 Kollus 플레이어와 통신하여, 재생 상태를 제어하거나 실시간 이벤트를 수신할 수 있게 해주는 JavaScript 라이브러리입니다.

주요 특징

  • 통합 제어: 플레이어 종류에 관계없이 동일한 코드로 제어할 수 있습니다.
  • 간결한 구현: 별도의 외부 라이브러리 없이 독립적으로 동작합니다.
  • 직관적 사용: 단순화된 메서드와 이벤트 리스너 구조를 지원합니다.

용어 정의

본 가이드에서 사용하는 주요 기술 용어와 플레이어 버전에 대한 정의입니다.

용어설명
VideoGateway시청자(End User)의 요청에 따라 재생 데이터를 전달하는 서버
플레이어 ID시청자 기기 고유 식별자
하드웨어 ID시청자 기기 시리얼 넘버
HLS FragmentHLS(HTTP Live Streaming) 프로토콜 기반 재생 시 전체 영상을 잘게 나눈 최소 단위의 미디어 파일
v3Html5 Player for PC (hybrid): 암호화된 콘텐츠를 Microsoft Edge 또는 Chrome 45 이상의 브라우저에서 재생할 때 사용되는 하이브리드 HTML5 플레이어
v4Html5 Player for All: 비암호화 콘텐츠 전용 비설치형 HTML5 Player
v5Web Player: 설치형과 비설치형의 장점을 결합한 통합 웹 플레이어
ℹ️참고

플레이어별 상세 설명은 Kollus 플레이어 종류 문서를 참고하세요.


라이브러리 설치 및 초기화

먼저 클라이언트 스크립트를 로드하고, 제어할 iframe을 대상으로 하는 인스턴스를 생성합니다.

기본 구현 예제

<script src="/path/to/vg-controller-client.1.1.16.min.js"></script>
<script>
window.onload = function () {
try {
var controller = new VgControllerClient({
target_window: document.getElementById('child').contentWindow,
});
// 이벤트 리스너 등록 및 메서드 호출
} catch (e) {
console.error(e);
}
};
</script>
<body>
<iframe id="child" src="http://v.kr.kollus.com/..."></iframe>
</body>

주의 사항

  • 대상 지정: target_window 속성에는 반드시 대상 iframe 요소의 contentWindow 객체를 직접 전달해야 합니다.
  • 브라우저 호환성: 본 라이브러리는 window.postMessage API를 사용하여 통신합니다. 해당 API를 지원하지 않는 오래된 브라우저에서는 작동하지 않습니다.
  • 다중 플레이어 제어: 한 페이지 내에 여러 개의 플레이어(iframe)가 존재할 경우, iframe의 ID를 구분하여 개별 인스턴스를 생성해야 합니다.

예외 코드

초기화 및 통신 과정에서 오류 발생 시 반환되는 코드입니다.

코드메시지설명
-1*postMessage 통신 중 발생한 예외
-99player type is not defined플레이어 종류가 명시되지 않음
-99player type must be one of v2, v3, v4 and flash지원하지 않는 플레이어
-99this browser does not support postMessage브라우저가 postMessage API를 지원하지 않음
-99listener is not callable등록하려는 이벤트 리스너가 유효한 함수가 아님

CDN 경로

플레이어 제어 스크립트(VG Controller)는 CDN을 통해 제공됩니다.

최신 버전

<script src="https://file.kollus.com/vgcontroller/vg-controller-client.latest.min.js"></script>

특정 버전

<script src="https://file.kollus.com/vgcontroller/vg-controller-client.1.1.4.min.js"></script>

보안 강화 (Integrity 속성)

CDN을 통한 라이브러리 로드 시, 파일의 변조 여부를 검증하기 위해 SRI(Subresource Integrity) 속성을 사용하는 것이 권장됩니다.

<script src="https://file.kollus.com/vgcontroller/vg-controller-client.1.2.3.min.js"
integrity="sha256-esUCCL4RPYMS8AR+Sl3lNrFa5M+zgpt4Gb77qtz66OY="
crossorigin="anonymous">
</script>
ℹ️참고

버전별 Integrity 속성(Integrity Code)은 링크를 참고하세요.


이벤트 리스닝

controller.on() 메서드를 사용하여 플레이어에서 발생하는 다양한 이벤트를 실시간으로 수신할 수 있습니다.

단일 리스너 등록

controller.on('event_name', function(param) {
// 이벤트 리스너
});

다중 리스너 등록

controller.on('event_name', function(param) {
// 첫 번째 리스너
});
controller.on('event_name', function(param) {
// 두 번째 리스너
});
// 이벤트 발생 시 모든 리스너 실행

메서드 체이닝 (Method Chaining)

연속적인 이벤트 등록을 간결한 코드로 구현할 수 있습니다.

controller.on('event_name_1', function(param) {
// 첫 번째 리스너
}).on('event_name_2', function(param) {
// 두 번째 리스너
});
⚠️주의

JavaScript의 비동기 이벤트 루프 특성상, 동일한 이벤트에 등록된 여러 리스너 간의 실행 순서는 보장되지 않습니다.

  • 권장 사항: 특정 작업이 반드시 순차적으로 진행되어야 하는 로직이라면, 여러 개의 리스너로 나누지 말고 하나의 리스너 내부에서 순차적으로 코드를 작성하는 것이 안전합니다.

이벤트 목록

재생 상태 이벤트

이벤트지원 플레이어설명
loadedv3, v4플레이어 로딩이 완료된 시점에 발생합니다.
readyv3, v4서버로부터 재생 데이터를 받아 재생 준비가 완료되었을 때 발생합니다.
playv3, v4최초 재생이 시작되거나 일시정지 상태에서 재생이 재개될 때 발생합니다.
pausev3, v4재생이 일시적으로 중단될 때 발생합니다.
donev3, v4재생 시점이 콘텐츠의 전체 길이(duration) 끝에 도달했을 때 발생합니다.
waitingv4네트워크 문제로 추가 로딩이 필요한 경우, 정상화 전까지 1초 주기로 발생합니다.

진행률(Progress) 이벤트

이벤트지원 플레이어설명
progressv3, v4재생 중에 1초 간격으로 발생합니다.

progress 파라미터 상세

파라미터타입설명
percentinteger현재 재생 진행률(0~100)
positionnumber현재 재생 위치(단위: 초, 소수점 5자리)
durationnumber콘텐츠 전체 길이(단위: 초, 소수점 5자리)
controller.on('progress', function(percent, position, duration) {
console.log(percent + '%', position + '초');
});
⚠️주의

HTML5 기반 플레이어의 특성상, progress 이벤트는 정확히 1초 간격으로 발생하지 않을 수 있습니다.
네트워크 및 브라우저 성능에 따라 약 0.1~0.5초의 오차가 발생할 수 있음에 유의하세요.

탐색(Seek) 이벤트

이벤트지원 플레이어설명
seekingv4시청자가 재생 시점을 이동하기 시작했을 때 발생합니다.
seekedv4재생 시점 이동 작업이 완료되었을 때 발생합니다.
seek_startv4, v5재생 시점 이동이 감지된 시점에 호출됩니다.

음향 이벤트

이벤트지원 플레이어설명
mutedv3, v4음소거 상태가 변경되었을 때 발생합니다.
volumechangev3, v4음량이 변경되었을 때 발생합니다.

muted 파라미터 상세

파라미터타입설명
is_mutedboolean
  • true: 음소거
  • false: 음소거 해제

volumechange 파라미터 상세

파라미터타입설명
volumeinteger변경된 음량(0~100)

재생속도(배속) 이벤트

이벤트지원 플레이어설명
speedchangev3, v4현재 재생 속도가 변경될 때 발생합니다.
playbackrateschangev3, v4선택 가능한 배속값 그룹이 변경될 때 발생합니다.

speedchange 파라미터 상세

파라미터타입설명
speedstring변경된 배속(0.5~4)

화면 이벤트

이벤트지원 플레이어설명
screenchangev3, v4전체 화면 모드와 일반 화면 모드 간의 전환 시 발생합니다.
device_orientation_changedv4모바일 기기의 화면 방향이 가로 또는 세로로 회전할 때 발생합니다.
user_active_changedv4사용자 인터랙션에 의해 컨트롤바가 활성화 또는 비활성화될 때 발생합니다.

screenchange 파라미터 상세

파라미터타입설명
screenstring
  • windowed: 일반 화면 모드
  • fullscreen: 전체 화면 모드

device_orientation_changed 파라미터 상세

파라미터타입설명
orientationstring
  • Portrait: 세로 방향
  • Landscape: 가로 방향

자막 이벤트

이벤트지원 플레이어설명
subtitle_load_donev3, v4자막 파일 로드가 완료되었을 때 발생합니다.
subtitlevisibilitychangev3, v4자막의 표시 상태(보임/숨김)가 변경되었을 때 발생합니다.

스트리밍 이벤트

이벤트지원 플레이어설명
hls_manifest_loadedv4HLS Manifest 파일 로드가 완료되었을 때 발생합니다.
dash_manifest_loadedv4DASH Manifest 파일 로드가 완료되었을 때 발생합니다.
bitrate_data_loadedv4재생 가능한 비트레이트 데이터 로드 완료 시 발생합니다.(비트레이트 기준 오름차순 정렬)
hlsfragchangev4HLS Fragment가 변경될 때 발생합니다.

bitrate_data 구조 예시

controller.on('bitrate_data_loaded', function(bitrate_data) {
// bitrate_data 구조: [{ width: <int>, height: <int>, bitrate: <int> }]
});

기타 이벤트

이벤트지원 플레이어설명
errorv3, v4재생 중 시스템 오류가 발생했을 때 호출됩니다.
html5_video_supportedv3, v4브라우저의 HTML5 Video 기능 지원 여부 확인 시 호출됩니다.
jumpstepchangev3, v4구간 이동(빨리감기/되감기)의 시간 단위가 변경될 때 발생합니다.
videosettingchangev3비디오 속성 변경 시 발생합니다.(V2 Player 전용)
bookmark_changev3북마크 추가, 업데이트, 삭제 시 발생합니다.
next_episode_auto_changev3, v4, v5다음 회차 재생 설정이 변경될 때 발생합니다.
next_episode_requestedv3, v4, v5다음 회차 콜백이 호출되었을 때 발생합니다.
picture_in_picture_enteredv3, v4, v5PIP(Picture-in-Picture) 모드에 진입했을 때 발생합니다.
picture_in_picture_leavedv3, v4, v5PIP 모드가 종료되었을 때 발생합니다.

메서드 사용법

기본 호출

controller.play();

파라미터 전달

controller.set_volume(90);

메서드 목록

이벤트 리스너 메서드

메서드지원 플레이어설명
on(event_name, callback)v3, v4이벤트 리스너를 등록하고, VgControllerClient 객체를 반환합니다.
off(event_name)v3, v4지정한 이벤트에 등록된 모든 리스너를 일괄 제거합니다.

재생 메서드

메서드지원 플레이어설명
play([start_at])v3, v4재생을 시작합니다. start_at(단위: 초) 지정 시 해당 시점부터 재생합니다.
pause()v3, v4현재 재생 중인 콘텐츠를 일시정지합니다.
toggle_pip()v3, v4PIP(Picture-in-Picture) 모드를 활성화하거나 비활성화합니다.
get_progress()v3, v4현재 재생 정보를 {percent, position, duration} 형태로 반환합니다.

play 메서드 호출 예시

controller.play();       // 처음부터 재생
controller.play(10); // 10초부터 재생

탐색(Seek) 메서드

메서드지원 플레이어설명
ff()v3, v4설정된 jumpstep만큼 앞으로 이동합니다.(빨리감기. 기본값: 10초)
rw()v3, v4설정된 jumpstep만큼 뒤로 이동합니다.(되감기. 기본값: 10초)
set_current_time(time)v3, v4현재 재생 상태를 유지하며 time(단위: 초) 위치로 시점을 이동합니다.
get_current_time()v3, v4현재 재생 위치를 초 단위(소수점 5자리)로 반환합니다.
set_jumpstep(jumpstep)v3, v4ff() 또는 rw() 호출 시 이동할 시간(단위: 초)을 설정합니다.
get_jumpstep()v3, v4현재 설정된 jumpstep 값을 반환합니다.
set_keyframe_seek_default(is_default)V2키프레임 단위 이동을 기본 동작으로 설정합니다.
ℹ️참고

play([start_at])set_current_time(time)의 차이

  • play(10): 10초 위치로 이동한 후 즉시 재생
  • set_current_time(10): 10초 위치로 이동하지만, 기존의 재생/일시정지 상태 유지

음향 메서드

메서드지원 플레이어설명
set_volume(volume)v3, v4음량을 설정합니다.(0~100)
get_volume()v3, v4현재 설정된 음량 값을 반환합니다.
mute()v3, v4음소거 상태를 변경합니다.(On/Off)

화면 메서드

메서드지원 플레이어설명
set_screen()v3, v4전체 화면 모드와 일반 화면 모드를 전환합니다.
get_screen()v3, v4현재 화면 모드를 반환합니다.
  • windowed: 일반 화면 모드
  • fullscreen: 전체 화면 모드
set_fullscreen_element(element)v3, v4전체 화면으로 표시할 대상 DOM 요소를 지정합니다.
enable_fullscreen_button()v3, v4플레이어 UI 내의 전체 화면 모드 버튼을 활성화합니다.
set_video_visibility(visibility)v3, v4비디오 화면의 표시 여부를 설정합니다.(오디오는 유지됩니다.)
get_video_visibility()v3, v4비디오 화면의 표시 여부를 반환합니다.
set_ratio(type)v3, v4화면 확대 방식을 설정합니다.
  • contain: 콘텐츠 비율에 맞게 화면에 맞춤
  • fill: 화면 전체를 채움
  • enlargement: 세로 길이에 맞춤(좌우 스크롤 발생)
⚠️주의

set_screen() 메서드는 Flash Player 및 FireFox 브라우저에서 지원되지 않습니다.

컨트롤바 메서드

메서드지원 플레이어설명
set_control_visibility(visibility)v3, v4내장 컨트롤바의 표시 여부를 설정합니다.
get_control_visibility()v3, v4내장 컨트롤바의 현재 표시 여부를 반환합니다.
set_controls_inactive_time(time)v3, v4컨트롤바가 자동으로 숨겨지는 시간을 설정합니다.(0: 상시 고정)
get_controls_inactive_time()v3, v4현재 설정된 컨트롤바 자동 숨김 시간을 반환합니다.
set_controls_activity(activity)v3, v4컨트롤바 활성화 여부를 설정합니다.
get_controls_activity()v3, v4컨트롤바의 현재 활성화 상태를 반환합니다.
set_controlbar_progress_only(enable)v3, v4컨트롤바에서 프로그레스바만 노출하고, 다른 버튼은 숨기도록 설정합니다.
get_controlbar_progress_only()v3, v4프로그레스바 단독 표시 여부를 반환합니다.
set_controlbar_hide_playing(enable)v4재생 중에만 컨트롤바를 자동으로 숨길지 여부를 설정합니다.
get_controlbar_hide_playing()v4재생 중 컨트롤바 숨김 설정 여부를 반환합니다.
hide_controlbar_button(value)v3, v4, v5지정한 버튼을 컨트롤바에서 숨깁니다.(ready 이벤트 이후 호출 권장)
  • play: 재생
  • rewind: 되감기(rw)
  • forward: 빨리감기(ff)
  • repeat: 구간 반복
  • currenttime: 현재 재생 시간
  • durationtime: 총 재생 시간
  • quality: 화질
  • playbackrate: 재생속도(배속)
  • mute: 음소거
  • volume: 볼륨 그래프
  • subtitle: 자막
  • setting: 설정
  • fullscreen: 전체 화면 모드
  • chat: 채팅
  • pip: PIP 모드
  • bigplay: 중앙 재생 버튼(Web Player)
  • seekcontainer: 모바일 좌우 되감기/빨리감기(Web Player)

hide_controlbar_button 메서드 호출 예시

// 컨트롤바에서 전체 화면 모드 및 설정 버튼 숨기기
controller.hide_controlbar_button(['fullscreen', 'setting']);

재생속도(배속) 메서드

메서드지원 플레이어설명
set_speed(speed)v3, v4재생속도를 0.5~4 범위에서 0.1초 단위로 설정합니다.
get_speed()v3, v4현재 재생속도를 문자열 형태로 반환합니다.
set_playback_rates(rates)v3, v4배속값 그룹을 설정합니다.
get_playback_rates()v3, v4배속값 그룹을 문자열 형태로 반환합니다.

메서드 호출 예시

// 단일 배열: 배속 옵션을 한 줄로 나열
controller.set_playback_rates([0.5, 1, 1.5, 2]);

// 이중 배열: [배속값 배열, 표시할 줄 수]
controller.set_playback_rates([[0.5, 1, 1.5, 2, 3, 4], 2]);
ℹ️참고

iOS 환경에서 HLS 기반 서비스를 이용할 경우, 최대 2배속까지만 지원 가능합니다.

구간 반복 메서드

메서드지원 플레이어설명
set_repeat_start([position])v3, v4구간 반복 시작 위치를 설정합니다.(생략 시 현재 위치 사용)
set_repeat_end([position])v3, v4구간 반복 종료 위치를 설정합니다.(생략 시 현재 위치 사용)
unset_repeat()v3, v4활성화된 구간 반복 설정을 해제합니다.
get_repeat()v3, v4현재 구간 반복 상태 및 구간 정보를 {status, start, end} 형태로 반환합니다.

set_repeat 메서드 호출 예시

controller.set_repeat_start(10);  // 구간 반복 시작 위치를 10초로 설정
controller.set_repeat_end(20); // 구간 반복 종료 위치를 20초로 설정

북마크 메서드

메서드지원 플레이어설명
refresh_bookmark()v3, v4북마크 목록을 업데이트합니다.
get_bookmark_count()v3, v4모든 북마크, 공식 북마크, 내 북마크의 개수를 {all, index, user} 형태로 반환합니다.
set_bookmark_add_activation(activation)v3, v4, v5북마크 추가 버튼의 활성화 여부를 설정합니다.
set_bookmark_update_activation(activation)v3, v4, v5북마크 편집 버튼의 활성화 여부를 설정합니다.
⚠️주의

set_bookmark_add_visivilityset_bookmark_update_visivility 메서드는 더 이상 지원되지 않습니다.(deprecated)

자막 메서드

메서드지원 플레이어설명
set_subtitle(value)v3, v4자막 데이터(VTT URL 또는 RawData)를 직접 설정합니다.
set_subtitle_visibility(visibility)v3, v4자막의 표시 여부를 설정합니다.
set_subtitle_sub_visibility(visibility)v3, v4서브 자막의 표시 여부를 설정합니다.
set_subtitle_shadow_rect(is_rect)v3, v4자막 배경 스타일을 설정합니다.
get_subtitle_shadow_rect()v3, v4현재 자막 배경 스타일 설정값을 반환합니다.
set_subtitle_font_size(size)v3, v4자막의 폰트 크기(px)를 설정합니다.
get_subtitle_font_size()v3, v4현재 설정된 자막 폰트 크기를 반환합니다.
set_subtitle_activity(activity)v3, v4자막의 표시 위치를 설정합니다.
get_subtitle_activity()v3, v4자막의 위치 정보를 반환합니다.
get_subtitles_list()v3, v4전체 자막 목록을 반환합니다.
get_subtitles_sub_list()v3, v4서브 자막 목록을 반환합니다.
set_current_subtitle(index)v3, v4특정 인덱스의 자막으로 변경합니다.
set_current_subtitle_sub(index)v3, v4특정 인덱스의 서브 자막으로 변경합니다.

비트레이트 메서드

메서드지원 플레이어설명
set_bitrate(index)v4지정한 인덱스의 비트레이트로 변경합니다.(0: 자동)
get_bitrate_data()v4사용 가능한 비트레이트 데이터를 반환합니다.
ℹ️참고

bitrate_data 배열의 index에 +1을 해야 실제 비트레이트 변경 요청이 가능합니다.(0: 자동)

플레이어 정보 메서드

메서드지원 플레이어설명
get_player_id()v3, v4플레이어 ID를 반환합니다.(ready 이벤트 이후 호출 가능)
get_hardware_id()v3하드웨어 ID를 반환합니다.(ready 이벤트 이후 호출 가능)
get_player_type()v3, v4현재 실행 중인 플레이어 종류를 반환합니다.
  • v3: Html5 Player for PC (hybrid)
  • v4: Html5 Player for All (비보안)
get_video_info()v3, v4콘텐츠의 해상도 및 비트레이트 정보를 {width, height, bitrate} 형태로 반환합니다.(ready 이벤트 이후 호출 가능)
get_lms_data()v3, v4학습 관리 시스템(LMS) 연동 데이터를 반환합니다.
get_hls_frag_data()v4HLS Fragment 관련 데이터를 반환합니다.
dispose()v4플레이어 인스턴스를 제거합니다.

커스텀 스킨 메서드

메서드지원 플레이어설명
get_custom_skin()v4현재 적용된 커스텀 스킨의 JSON 데이터를 반환합니다.(ready 이벤트 이후 호출 가능)
set_custom_skin(json_data)v4JSON 설정을 통해 커스텀 스킨을 변경합니다.(ready 이벤트 이후 호출 가능)

set_custom_skin 메서드 호출 예시

controller.set_custom_skin({
controlbar: {
enable: true,
backgroundColor: 123123,
backgroundAlpha: 0.2,
progressButton: {
enable: false
}
}
});

에러 메서드

메서드지원 플레이어설명
get_error_detail()v3, v4발생한 에러의 상세 정보를 {code, message, param} 형태로 반환합니다.
set_custom_error(code, message, param)v3, v4커스텀 에러 메시지를 플레이어에 설정합니다.

채팅 메서드

메서드지원 플레이어설명
set_chat_config(value)v3, v4채팅 관련 설정을 적용합니다.(ready 이벤트 이후 호출 가능)
notify_visibleheight_changed(height)v3, v4Android WebView에서 키보드 표시에 따른 화면 높이 변화를 전달합니다.

set_chat_config 메서드 호출 예시

controller.set_chat_config({
customer_page: [{
title: '강의 정보',
url: 'https://example.com'
// 또는 html: '<h2>HTML 내용</h2>'
}]
});
ℹ️참고
  • URL은 https 프로토콜만 허용됩니다.
  • html 본문에 포함된 script 태그는 실행되지 않습니다.

클로즈 이벤트 메서드

메서드지원 플레이어설명
set_enable_close_event()v3, v4브라우저 종료(close) 콜백 기능을 활성화합니다.
set_close_callback_fn(fn)v3, v4브라우저 종료 시 실행할 콜백 함수를 등록합니다.
get_enable_close_event()v3, v4브라우저 종료(close) 콜백 할성화 여부를 반환합니다.
set_close_button(enable, fn)v4모바일용 닫기 버튼을 생성하고, 클릭 이벤트를 설정합니다.(ready 이벤트 이후 호출 가능)

기타 메서드

메서드지원 플레이어설명
set_vr_overlay(options)v3, v4iOS 환경에서 VR 콘텐츠 재생을 위한 권한 요청 오버레이를 설정합니다.
set_short_key(enable)V2플레이어 단축키 활성화 여부를 설정합니다.
get_topmost()V2플레이어 창의 최상위 노출 설정 여부를 반환합니다.
set_topmost(topmost)V2플레이어를 항상 최상위 창으로 표시할지 여부를 설정합니다.
set_lms_check()V2브라우저 종료 시 LMS 데이터 전송 여부를 확인하도록 설정합니다.

모바일 VR 콘텐츠 재생 시 유의 사항

  • Android: iframe 환경에서 기기의 orientation(방향) 정보가 실제 화면과 동기화되지 않아, 360° VR 영상의 좌우 조작 방향이 반대로 동작하는 현상이 발생할 수 있습니다.
  • iOS: iOS 13 버전부터 보안 강화를 위해 DeviceMotion(가속도/자이로) 데이터 접근 시 사용자 승인이 필수입니다. 그러나 브라우저 보안 정책상 iframe 내부에서는 권한 요청 팝업을 띄울 수 없어 VR 조작이 작동하지 않습니다.

해결 방법

  • VG Controller 1.1.10 이상 버전을 사용하세요.
  • iOS 환경에서는 set_vr_overlay() 메서드를 반드시 호출하세요.
    var controller = new VgControllerClient({
    // 플레이어 iframe을 감싸고 있는 최상위 컨테이너 요소(Element)를 지정합니다.
    target_window: player.contentWindow
    });
    controller.set_vr_overlay({
    // 사용자에게 센서 권한 허용을 유도하는 안내 문구를 커스터마이징합니다.
    target_element: document.getElementById('player'),
    permission_request_help_message: '커스텀 메시지'
    });
🚨이슈

iOS 13.4 이상 버전에서는 DeviceMotion API의 rotationRate 값이 정상적으로 반환되지 않습니다.