공원에 웬 로봇이…커피 배달도 ‘척척’ (2025)

'; var _rptContent = rptHeader + rptScript + rptContent + rptReport + rptTail; var agent = navigator.userAgent.toLowerCase(); if ((agent.indexOf("msie") != -1)) //IE브라우저 10이하버전 // 11버전은 else 탐 { printHtml = rptContent + rptReport; var rptWin = window.open("/common/printPop.html", "rpt", "width=" + w + ",height=" + h + ",top=" + ypos + ",left=" + xpos + ",status=yes,scrollbars=yes"); } else { var rptWin = window.open("", "rpt", "width=" + w + ",height=" + h + ",top=" + ypos + ",left=" + xpos + ",status=yes,scrollbars=yes"); rptWin.document.open(); rptWin.document.write(_rptContent); rptWin.document.close(); }}function displayMetaTag() { var metaTag = ''; var arrString = []; var listHtml = ""; if (!isEmpty(metaTag)) { arrString = metaTag.split("|"); for (var i = 0; i < arrString.length; i++) { listHtml += '

  • #' + arrString[i] + '
  • '; } $('#hashList').html(listHtml); }}// ------------------------------------------------var modArrImg = [];var modBxObj = [];var searchTemp = '';function fnModSetContentsView(tagNm, tagType, TagKey) { modArrImg.push({"TAG_ID": tagNm, "TAG_LIST": null}); switch (tagType) { case "VIDEO": { modGetVideo(tagNm, TagKey); } break; case "VOD": { modGetVod(tagNm, TagKey); } break; case "NEWSVIDEO": { modGetNewsVideo(tagNm, TagKey); } break; }};function modGetNewsVideo(tagNm, TagKey) { var tagArr = []; tagArr = TagKey.split("_"); var ncd = tagArr[0]; var mediaSeq = tagArr[1]; var url = application.rootUrlPrefix + '/api/getNewsInfo'; var param = { newsCode: ncd }; postAjax(url, param, function (result, status) { modNewsVideoDisplay(result, tagNm, mediaSeq); });};function modNewsVideoDisplay(data, tagNm, mediaSeq) { var listTag = null; var list;if (data && data.data) {list = data.data;} var thumbnailImageUrl = ""; var caption = ""; var srtUrl = ""; var vodCaption = ""; var dutyYN = ""; var vodBlockingYn = ""; var vodTypeArr = []; var vodCheck = false; if (list && list.vods && !isEmpty(list.vods)) { var lowVodUrl = ""; var highVodUrl = ""; for (var i = 0; i < list.vods.length; i++) { var temp = list.vods[i]; if (temp.mediasetSeq == mediaSeq) { vodTypeArr.push(temp.vodType); thumbnailImageUrl = temp.thumbnailImageUrl; caption = temp.caption; srtUrl = temp.subtitleUrl; vodCaption = temp.caption; dutyYN = temp.dutyYn; vodBlockingYn = temp.vodBlockingYn; if (temp.vodType == 'D') lowVodUrl = temp.vodUrl; else if (temp.vodType == 'G') highVodUrl = temp.vodUrl; else if (temp.vodType == 'K') highVodUrl = temp.vodUrl; } } vodTypeArr.sort(); if (lowVodUrl == highVodUrl || highVodUrl == "" || lowVodUrl == "") { vodCheck = true; } } listTag = modGetTagList(tagNm); listTag.TAG_LIST = { 'NEWS_CODE': list && list.newsCode ? list.newsCode : "", 'MEDIASET_SEQ': mediaSeq, 'VOD_TYPE': vodTypeArr, 'IMG_URL': thumbnailImageUrl, 'NEWS_TITLE': list && list.newsTitle ? list.newsTitle : "", 'srtUrl': srtUrl, 'dutyYn': dutyYN, 'vodBlockingYn': vodBlockingYn }; var k = $("#vod_template").clone(); k.removeAttr('id'); k.css('display', 'block'); k.find('.player-wrap .multi_player').attr('id', 'player_' + tagNm); k.find('.player-wrap .multi_player_image').attr('id', 'thumbnail_player_' + tagNm); var playerInitialValue = { newsCode: "8346114", playerId: 'player_' + tagNm, imgUrl: application.rootUrlPrefix + thumbnailImageUrl, lowVodUrl: lowVodUrl, highVodUrl: highVodUrl, caption: caption } $(".view-article #" + tagNm).html(k); var originalWidth = 912; var originalHeight = 513; $('#player_' + tagNm).css("max-height", "0"); // 동영상 관련 하단 설명 $('#player_' + tagNm).closest('.player-wrap').next('.player-caption').text(caption); var $thumbnail = $('#thumbnail_player_' + tagNm); var $img = $thumbnail.find("img"); $img.css("width", originalWidth); $img.css("height", originalHeight); var $playBtn = $thumbnail.find(".play-button"); $img.attr("src", application.rootUrlPrefix + thumbnailImageUrl); $thumbnail.show(); $playBtn.off("click").on("click", function (e) { $thumbnail.hide(); $('#player_' + tagNm).css("max-height", originalHeight); new _KbsPlayer(playerInitialValue); });};function modGetTagList(tagNm) { for (var i = 0; i < modArrImg.length; i++) { if (modArrImg[i].TAG_ID == tagNm) { listTag = modArrImg[i]; break; } } return listTag;};//비디오function modGetVideo(tagNm, TagKey) { var url = application.rootUrlPrefix + '/api/getNewsInfo'; var param = { newsCode: TagKey, }; postAjax(url, param, function (result, status) { modVideoDisplay(result, tagNm); });};function modVideoDisplay(data, tagNm) { var listTag = null; var list = data.data; var length = 0; var imgUrl = ""; if (!isEmpty(list.images)) { imgUrl = list.images[0].imgUrl; } else { imgUrl = application.vodDefaultImage; } var lowVodUrl = ""; var highVodUrl = ""; if (list && list.vods && !isEmpty(list.vods)) { for (var i = 0; i < list.vods.length; i++) { var temp = list.vods[i]; if (temp.vodType == 'D') lowVodUrl = "|N|N|N|" + temp.vodUrl; else if (temp.vodType == 'K') highVodUrl = "|N|N|N|" + temp.vodUrl; } } listTag = modGetTagList(tagNm); listTag.TAG_LIST = { 'NEWS_CODE': list && list.newsCode ? list.newsCode : "", 'LOW_VOD_URL': lowVodUrl, 'HIGH_VOD_URL': highVodUrl, 'IMG_URL': imgUrl, 'NEWS_TITLE': list && list.newsTitle ? list.newsTitle : "" }; var k = $("

    동영상영역 시작

    공원에 웬 로봇이…커피 배달도 ‘척척’ (1)

    동영상영역 끝

    동영상설명

    "); k.find(".view").attr('id', "player_" + tagNm); k.find("img").attr('id', "img_" + tagNm); if (isEmpty(imgUrl)) { k.find("img").attr('src', application.vodDefaultImage); } else { k.find("img").attr('src', application.imagePath + imgUrl); } k.find("img").attr('alt', list.newsTitle); k.find("button").attr('onClick', "modPlayVideo( \'" + tagNm + "\' );"); k.find("em").text(list.newsTitle); $("#cont_newstext #" + tagNm).html(k); var l = $("

    공원에 웬 로봇이…커피 배달도 ‘척척’ (2)

    "); if (isEmpty(imgUrl)) { l.find("img").attr('src', application.vodDefaultImage); } else { l.find("img").attr('src', application.imagePath + imgUrl); } l.find("img").attr('alt', newsTitle); $("#mailHtmlContents #" + tagNm).html(l);};function modPlayVideo(tagNm) { var listTag = modGetTagList(tagNm); var list = listTag.TAG_LIST; var vodUrl; var vodQualityType = "" + getCookie("vod_quality_type"); if (vodQualityType == "low") { vodUrl = getKBSHlsVodUrl(list.LOW_VOD_URL); } else { vodUrl = getKBSHlsVodUrl(list.HIGH_VOD_URL); } if (isEmpty(vodUrl)) return; var image = list.IMG_URL; if (list.srtUrl != "" && list.srtUrl != 'undefined' && list.srtUrl != undefined) { var vodParam = { playlist: [{ image: image, file: vodUrl, tracks: [{file: list.srtUrl, "default": "false"}] }], skin: 'kbsvod', autostart: "true", //자동시작 height: 422, width: 750, vodPlayListInfo: [{newscode: list.NEWS_CODE}] }; } else { var vodParam = { playlist: [{ image: image, file: vodUrl }], skin: 'kbsvod', autostart: "true", //자동시작 height: 422, width: 750, vodPlayListInfo: [{newscode: list.NEWS_CODE}] }; } jwPlayerPlayNew(vodParam, 'player_' + tagNm); //동영상 재생 if (list.srtUrl != "" && list.srtUrl != 'undefined' && list.srtUrl != undefined) { setTimeout(function () { $("#player_" + tagNm + " .jw-icon-cc").show(); }, 1000); }};function modGetVod(tagNm, TagKey) { var listTag = null; var arr_key = TagKey.split("|"); var loopCnt = arr_key.length; if (loopCnt < 3) return false; var vodUrl = ""; var imgUrl = ""; var newsTitle = ""; for (var i = 0; i < loopCnt; i++) { if (i == (loopCnt - 1)) { newsTitle = arr_key[i]; } else if (i == (loopCnt - 2)) { imgUrl = arr_key[i]; } else { if (isEmpty(vodUrl)) { vodUrl = arr_key[i]; } else { vodUrl += "|" + arr_key[i]; } } } if (vodUrl.indexOf('|') == -1) { vodUrl = "|N|N|N|" + vodUrl; } else { vodUrl = "|" + vodUrl; } listTag = modGetTagList(tagNm); listTag.TAG_LIST = {'VOD_URL': vodUrl, 'IMG_URL': imgUrl, 'NEWS_TITLE': newsTitle}; var k = $("

    동영상영역 시작

    공원에 웬 로봇이…커피 배달도 ‘척척’ (3)

    동영상영역 끝

    동영상설명

    "); k.find(".view").attr('id', "player_" + tagNm); k.find("img").attr('id', "img_" + tagNm); if (isEmpty(imgUrl)) { k.find("img").attr('src', application.vodDefaultImage); } else { k.find("img").attr('src', application.imagePath + imgUrl); } k.find("img").attr('alt', newsTitle); k.find("button").attr('onClick', "modPlayVod( \'" + tagNm + "\' );"); if (imgUrl.indexOf('/data/fckeditor/vod/') > -1) { k.find("em").text(newsTitle); } else { k.find("em").remove(); } $("#cont_newstext #" + tagNm).html(k); var l = $("

    공원에 웬 로봇이…커피 배달도 ‘척척’ (4)

    "); if (isEmpty(imgUrl)) { l.find("img").attr('src', application.vodDefaultImage); } else { l.find("img").attr('src', application.imagePath + imgUrl); } l.find("img").attr('alt', newsTitle); $("#mailHtmlContents #" + tagNm).html(l);};function modPlayVod(tagNm) { var listTag = modGetTagList(tagNm); var list = listTag.TAG_LIST; var vodUrl = getKBSHlsVodUrl(list.VOD_URL); if (isEmpty(vodUrl)) return; var image = ""; if (isEmpty(list.IMG_URL)) { image = application.vodDefaultImage; } else { image = list.IMG_URL; } var vodParam = { playlist: [{ image: image, file: vodUrl }], skin: 'kbsvod', autostart: "true", //자동시작 height: 422, width: 750 }; jwPlayerPlayNew(vodParam, 'player_' + tagNm); //동영상 재생};function modPlayNewsVideo(tagNm) { var listTag = modGetTagList(tagNm); var list = listTag.TAG_LIST; var vodUrl; if (list.dutyYN == 'Y') { popAlert('I', '저작권 관련 서비스 사용이 불가합니다.'); return; } if (list.vodBlockingYn == 'Y') { var blocking = ''; var url = application.rootUrlPrefix + '/api/getIpInfo'; var param = {}; postAjax(url, param, function (result, status) { if (!isEmpty(result.isAbroadIp)) { blocking = data.isAbroadIp; //해외 IP 확인 } }, function (result, status) { blocking = 'N'; }); if ("N" == blocking) { popAlert('I', '저작권 관련 서비스 사용이 불가합니다.'); return; } } var vodQualityType = "" + getCookie("vod_quality_type"); var lowType = list.VOD_TYPE[0]; var highType = list.VOD_TYPE[list.VOD_TYPE.length - 1]; if (vodQualityType == "low") { vodUrl = getNewsVodOneTimeUrl(list.NEWS_CODE, lowType, list.MEDIASET_SEQ); } else { vodUrl = getNewsVodOneTimeUrl(list.NEWS_CODE, highType, list.MEDIASET_SEQ); } if (isEmpty(vodUrl)) return; var image = list.IMG_URL; if (list.srtUrl != "" && list.srtUrl != 'undefined' && list.srtUrl != undefined) { var vodParam = { playlist: [{ image: image, file: vodUrl, tracks: [{file: list.srtUrl, "default": "false"}] }], skin: 'kbsvod', autostart: "true", //자동시작 height: 422, width: 750, vodPlayListInfo: [{newscode: list.NEWS_CODE}] }; } else { var vodParam = { playlist: [{ image: image, file: vodUrl }], skin: 'kbsvod', autostart: "true", //자동시작 height: 422, width: 750, vodPlayListInfo: [{newscode: list.NEWS_CODE}] }; } jwPlayerPlayNew(vodParam, 'player_' + tagNm); //동영상 재생 if (list.srtUrl != "" && list.srtUrl != 'undefined' && list.srtUrl != undefined) { setTimeout(function () { $("#player_" + tagNm + " .jw-icon-cc").show(); }, 1000); }};function getNewsVodOneTimeUrl(ncd, vodType, mediaseq) { var url = application.rootUrlPrefix + '/api/getNewsVodOneTimeUrl'; var param = { mediasetSeq: mediaseq, newsCode: ncd, vodType: vodType }; postAjax(url, param, function (result, status) { if (result.success) { streamUrl = data.data.streamUrl; } else { streamUrl = null; alert(result.message); } }, function (result, status) { streamUrl = null; popAlert('E', 'VOD Url 정보를 가지고 오는데 실패하였습니다. >> [' + error + ']'); }); return streamUrl;}function setNextNewsVod() { var url = application.rootUrlPrefix + '/api/getPreNextNews'; var param = { newsCode: newsCode, }; postAjax(url, param, function (result, status) { var prevNextNews = result.data; if (prevNextNews == null || prevNextNews.nextNews == null) { return; } var nextNews = prevNextNews.nextNews; $('#preNewsDiv').show(); $('#nextNewsDiv').show(); $('#nextNewsUrl').attr('href', '/news/view.do?ncd=' + nextNews.newsCode); $('#nextNewsImg').attr('src', nextNews.imgUrl); $('#nextNewsTitle').html(nextNews.newsTitle); });}function setKeyword() { var keyword = '' if (keyword) { var keywordList = keyword.split('|'); for (var i = 0; i < keywordList.length; i++) { var $li = $('.hashtag-links-wrapper ul li').first().clone(); $li.find('a').html("#" + keywordList[i]).attr('href', "/news/pc/search/search.do?query=" + decodeHtmlEntities(keywordList[i])); $('.hashtag-links-wrapper ul').append($li); } $('.hashtag-links-wrapper ul li').first().remove(); }}function decodeHtmlEntities(input) { var doc = new DOMParser().parseFromString(input, "text/html"); return doc.documentElement.textContent;}function newsContentsDecorate() { function anchorProperties(iconName) { return { section_color: "#4664e6", div_color: "#f7fbff", div_background: "rgb(18 18 55 / 4%)", font_color: "#121237", icon_name: iconName, class: "badge", parentsClass: "anchor-text" }; } function reporterProperties(iconName) { return { section_color: "#db9655", div_color: "#fefcfb", div_background: "rgb(0 128 204 / 4%)", font_color: "#0080CC", icon_name: iconName, class: "badge", parentsClass: "report-text" }; } var section_map = { "[앵커]": anchorProperties("앵커"), "<앵커 멘트>": anchorProperties("앵커"), "[질문]": anchorProperties("질문"), "⊙인터뷰:": anchorProperties("인터뷰"), "[기자]": reporterProperties("기자"), "⊙기자:": reporterProperties("기자"), "[리포트]": reporterProperties("리포트"), "<리포트>": reporterProperties("리포트"), "[답변]": reporterProperties("답변") }; // split var list = [{section: "전체", contents: $("#cont_newstext").html()}]; for (var s in section_map) { list = newsContentsSplitByWord(list, s); } // decorate var decorated_html;if (list[0] && list[0].contents) {decorated_html = list[0].contents;} for (var a = 1; a < list.length; a++) { var obj = list[a]; var map = section_map[obj.section]; decorated_html += '

    '; decorated_html += '

    '; decorated_html += '' + map.icon_name + ''; decorated_html += '

    ' + obj.contents.replace(/^\s*
    /, '') + '

    '; decorated_html += '

    '; decorated_html += '

    '; } $("#cont_newstext").html(decorated_html);}function newsContentsSplitByWord(list, word) { var ret = []; for (var a = 0; a < list.length; a++) { var subList = []; if (list[a] && list[a].contents) { subList = list[a].contents.split(word); } for (var b = 0; b < subList.length; b++) { if (b == 0) { ret.push({section: list[a].section, contents: subList[b]}); continue; } ret.push({section: word, contents: subList[b]}); } } return ret;}

    뉴스광장

    공원에 웬 로봇이…커피 배달도 ‘척척’

    입력 2025.09.02 (08:01) 수정 2025.09.02 (08:05)

    읽어주기 기능은 크롬기반의
    브라우저에서만 사용하실 수 있습니다.

    `; $(`#${playerId}`).find(".jw-display-controls.jw-reset").append(HTML); const $forwardButton = $(`#${playerId}`).find(".jw-icon-forward"); $forwardButton.on("click", ()=>{ self.moveForward(); }); } // 볼륨 조절 시 볼륨 값 표시 영역 세팅 this.preRenderVolumeValueDisplay = function () { const playerId = self.settings.playerId; const HTML = `

    `; $(`#${playerId}`).append(HTML); } // 키보드 조작 이벤트 this.preRenderKeyboardControl = function() { document.getElementById(self.settings.playerId).addEventListener('keydown', function (e) { const playerId = self.settings.playerId; const state = jwplayer(playerId).getState(); if (e.keyCode == 37) { // ← self.moveBackward(); e.preventDefault(); } else if (e.keyCode == 39) { // → e.preventDefault(); if (state != 'complete') { self.moveForward(); } } else if (e.keyCode == 38) { // ↑ self.soundUp(); e.preventDefault(); } else if (e.keyCode == 40) { // ↓ self.soundDown(); e.preventDefault(); } else if (e.keyCode == 32) { // spaceBar self.pause(); e.preventDefault(); } else if (e.keyCode == 70) { // f self.fullscreen(); e.preventDefault(); } else if (e.keyCode == 77) { // m self.mute(); e.preventDefault(); } }); } // jwplayer에 키보드 컨트롤 안내창 삽입 this.preRenderKeyControlInfo = function () { const playerId = self.settings.playerId; const HTML = `

    `; $(`#${playerId}`).after(HTML); const $playerWrap = $(`#${playerId}`).parents('.player-wrap'); const $openKeyinfoButton = $playerWrap.find('.button-keyinfo'); const $closeKeyinfoButton = $playerWrap.find('.close-keyinfo'); const $keyinfoBox = $playerWrap.find(".keyinfo-box"); $openKeyinfoButton.on("click", () => $keyinfoBox.toggle()); $closeKeyinfoButton.on("click", () => $keyinfoBox.hide()); } // 스크롤 내렸을 때 동영상 띄우기 (pip mode) this.preRenderFloatingVideo = function() { var videoElements = document.querySelectorAll('video'); videoElements.forEach( video => video.setAttribute('disablePictureInPicture', 'true') ); var onScrollHandler = function () { if ( scrollY > 900 ) { $('.player-wrap').addClass('fix'); $('.player-app').addClass('fix'); } else { $('.player-wrap').removeClass('fix'); $('.player-app').removeClass('fix'); } }; self.vodPlayer.on("play", () => { $(window).on("scroll", onScrollHandler); }); } // AutoStart 세팅 (autoStart가 아닐 때 섬네일 이미지 세팅) this.preRenderAutoStart = function() { const isAutoStart = localStorage.getItem('jwplayer-autoStart') == 'true'; if (isAutoStart) return; var $thumbnail = $("#element-image"); var $img = $thumbnail.find("img"); var $playBtn = $thumbnail.find(".play-button"); $img.attr("src", application.rootUrlPrefix + "/data/news/title_image/newsmp4/newsplaza/2025/09/02/260_8346114.jpg"); $thumbnail.show(); $playBtn.off("click").on("click", function (e) { $thumbnail.hide(); self.vodPlayer.play(); }); } // preRenderErrorMessage (확인필요) this.preRenderErrorMessage = function() { if (this.vodPlayer.getPlaylist()[0].sources.length == 0) { var errMsg = $(".error-message"); errMsg.css("display", ""); errMsg.text(message); } } // 영상 재생 10초 뒤로 this.moveBackward = function () { this.moveSeek(-10) } // 영상 재생 10초 앞으로 this.moveForward = function () { this.moveSeek(10); } // 사운드 5포인트 크게 this.soundUp = function () { const playerId = self.settings.playerId; const volume = parseInt(self.vodPlayer.getVolume()); this.moveVolume(5); $(`#${playerId}`).find(".jw-animation.ani-volume").text(`${volume}%`); $(`#${playerId}`).find(".jw-animation.ani-volume").stop(true, true).fadeIn().delay(300).fadeOut(); } // 사운드 5포인트 작게 this.soundDown = function () { const playerId = self.settings.playerId; const volume = parseInt(self.vodPlayer.getVolume()); this.moveVolume(-5); $(`#${playerId}`).find(".jw-animation.ani-volume").text(`${volume}%`); $(`#${playerId}`).find(".jw-animation.ani-volume").stop(true, true).fadeIn().delay(300).fadeOut(); } // 재생 영상 앞으로 뒤로 이동시킴 this.moveSeek = function (sec) { var moveTo = this.vodPlayer.getPosition() + sec; if (moveTo < 0) { moveTo = 0 } else if (moveTo > this.vodPlayer.getDuration()) { moveTo = this.vodPlayer.getDuration() } this.vodPlayer.seek(moveTo) } // 사운드 볼륨을 크게 작게 함 this.moveVolume = function (percent) { var volume = this.vodPlayer.getVolume() + percent if (volume < 0) { volume = 0 } else if (volume > 100) { volume = 100 } this.vodPlayer.setVolume(volume) } // 영상 일시 정지하거나 다시 재생시킴 this.pause = function () { const state = this.vodPlayer.getState(); if (state == 'playing') { this.vodPlayer.pause() } else if (state == 'paused' || state == 'complete') { this.vodPlayer.play() } } // 영상 풀스크린으로 보이게 this.fullscreen = function () { if (this.vodPlayer.getFullscreen()) { this.vodPlayer.setFullscreen(false) } else { this.vodPlayer.setFullscreen(true) } } // 음소거 this.mute = function () { if (jwplayer().getMute()) { jwplayer().setMute(false); } else { jwplayer().setMute(true); } } // 자막 보이게 안 보이게 토글 기능 this.toggleCaption = function () { if( self.vodPlayer.getCurrentCaptions() == 0 ) { setCaptionsOn(self.vodPlayer); } else { setCaptionsOff(self.vodPlayer); } } // 영상 자동 재생 토글 toggleAutoStart this.toggleAutoStart = function () { self.settings.isAutoPlay = !self.settings.isAutoPlay; var $autoPlay = $(".jw-button-autostart"); $autoPlay.toggleClass('on'); if ($autoPlay.hasClass('on')) { localStorage.setItem('jwplayer-autoStart', 'true'); } else { localStorage.setItem('jwplayer-autoStart', 'false'); } } // 동영상 퍼가기 this.embedVideo = function () { var vod = ''; if (hiVod) { vod = hiVod; } else { vod = lowVod; } var embedVideoUrl = application.rootUrlPrefix + '/news/pc/view/embedVideo.do?vodUrl=' + vod + '&imgUrl=' + self.settings.imgUrl + '&captionYn=' + captionYn; var embedUrl = '<iframe width="100%" height="100%" src="' + embedVideoUrl + '" ' + 'title="video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; ' + 'encrypted-media; gyroscope; web-share" allowfullscreen></iframe>'; $('.video-embed-popup .embed-text').html(embedUrl); $('.video-embed-popup').addClass("on"); $('.dim').addClass("on"); $('.body').addClass("on"); $('.header-nav-wrapper').addClass("index-change"); } var defaults = { playerWidth: 912, playerHeight: 513, isShortcuts: false, isAutoPlay: false, isCaption: true, vodPlayType: "vod_play_type", mediaFile: [], }; // jwplayer 기본 설정값 // 함수 arguments와 defaults 값을 가져와 settings에 기본 설정함 this.settings = (arguments[0] && typeof arguments[0] == "object") ? extendDefaults(defaults, arguments[0]) : defaults; var lowVod = "/newsmp4/newsplaza/2025/09/02/500k/260_8346114.mp4"; var hiVod = "/newsmp4/newsplaza/2025/09/02/1500k/260_8346114.mp4"; var captionYn = isEmptyStr("Y", 'N'); if (lowVod && lowVod != hiVod) { var cdnYn = 'N', duty = 'N', blockingYn = 'N'; if (lowVod.indexOf('|') == 0) { var vodInfos = lowVod.split('|'); duty = vodInfos[1]; cdnYn = vodInfos[2]; blockingYn = vodInfos[3]; lowVod = vodInfos[4]; } cdnYn = 'Y';//무조건 cdn으로 실행 if (duty.indexOf('^') >= 0) { var dutyInfos = duty.split('^'); dutyYn = dutyInfos[0]; if (dutyYn == 'Y') { duty_code = dutyInfos[1]; if (duty_code) { var dutyMsg = ''; $.ajax({ url: application.rootUrlPrefix + '/news/getVodDutyCodeMsg.do', type: "POST", async: false, dataType: 'json', data: { dutyCode: duty_code }, success: function (data, status) { if (data.dutyMsg && data.dutyMsg.resultcode == 1) { dutyMsg = data.dutyMsg.duty_msg; } else { dutyMsg = '저작권 관련 서비스 사용이 불가합니다.'; } }, error: function (request, status, error) { dutyMsg = '저작권 관련 서비스 사용이 불가합니다.'; } }); message = dutyMsg; return null; } } } else { dutyYn = duty; } if (dutyYn == 'Y') { message = '저작권 관련 서비스 사용이 불가합니다.'; return null; } if ("Y" == blockingYn) { var blocking = ''; $.ajax({ url: application.rootUrlPrefix + '/api/getIpInfo', type: "POST", async: false, dataType: 'json', success: function (data, status) { if (data.isAbroadIp) { blocking = data.isAbroadIp; //해외 IP 확인 } }, error: function (request, status, error) { blocking = 'N'; } }); if ("N" == blocking) { message = '저작권 관련 서비스 사용이 불가합니다.'; return; } } // VOD URL 조회 if (!lowVod) { message = 'VOD URL 정보가 없습니다.'; return null; } if (lowVod.indexOf("/") == 0) { lowVod = lowVod.substr(1); } var lowVodUrl = ""; var hiVodUrl = ""; $.ajax({ url: application.rootUrlPrefix + '/api/getHlsNewsVodUrl', type: "POST", dataType: 'json', data: { vodUrl: lowVod }, success: function (data, status) { if (data && data.success) { lowVodUrl = data.data.streamUrl; $.ajax({ url: application.rootUrlPrefix + '/api/getHlsNewsVodUrl', type: "POST", dataType: 'json', data: { vodUrl: hiVod }, success: function (data, status) { if (data && data.success) { hiVodUrl = data.data.streamUrl; self.SD = { file: lowVodUrl, label: '표준화질' } self.HD = { file: hiVodUrl, label: '고화질' } self.init(); } else { hiVodUrl = null; if (data && data.message) { message = data.message; } else { message = 'VOD Url 정보를 가지고 오는데 실패하였습니다.'; } self.init(); } }, error: function (request, status, error) { hiVodUrl = null; message = 'VOD Url 정보를 가지고 오는데 실패하였습니다. >> [' + error + ']'; self.init(); } }); } else { lowVodUrl = null; if (data && data.message) { message = data.message; } else { message = 'VOD Url 정보를 가지고 오는데 실패하였습니다.'; } const playerId = self.settings.playerId; displayErrorMessage(playerId, message); self.init(); } }, error: function (request, status, error) { lowVodUrl = null; message = 'VOD Url 정보를 가지고 오는데 실패하였습니다. >> [' + error + ']'; self.init(); } }); } else if (lowVod) { var cdnYn = 'N', duty = 'N', blockingYn = 'N'; if (lowVod.indexOf('|') == 0) { var vodInfos = lowVod.split('|'); duty = vodInfos[1]; cdnYn = vodInfos[2]; blockingYn = vodInfos[3]; lowVod = vodInfos[4]; } cdnYn = 'Y';//무조건 cdn으로 실행 if (duty.indexOf('^') >= 0) { var dutyInfos = duty.split('^'); dutyYn = dutyInfos[0]; if (dutyYn == 'Y') { duty_code = dutyInfos[1]; if (duty_code) { var dutyMsg = ''; $.ajax({ url: application.rootUrlPrefix + '/news/getVodDutyCodeMsg.do', type: "POST", async: false, dataType: 'json', data: { dutyCode: duty_code }, success: function (data, status) { if (data.dutyMsg && data.dutyMsg.resultcode == 1) { dutyMsg = data.dutyMsg.duty_msg; } else { dutyMsg = '저작권 관련 서비스 사용이 불가합니다.'; } }, error: function (request, status, error) { dutyMsg = '저작권 관련 서비스 사용이 불가합니다.'; } }); message = dutyMsg; return null; } } } else { dutyYn = duty; } if (dutyYn == 'Y') { message = '저작권 관련 서비스 사용이 불가합니다.'; return null; } if ("Y" == blockingYn) { var blocking = ''; $.ajax({ url: application.rootUrlPrefix + '/api/getIpInfo', type: "POST", async: false, dataType: 'json', success: function (data, status) { if (data.isAbroadIp) { blocking = data.isAbroadIp; //해외 IP 확인 } }, error: function (request, status, error) { blocking = 'N'; } }); if ("N" == blocking) { message = '저작권 관련 서비스 사용이 불가합니다.'; return; } } // VOD URL 조회 if (!lowVod) { message = 'VOD URL 정보가 없습니다.'; return null; } if (lowVod.indexOf("/") == 0) { lowVod = lowVod.substr(1); } var lowVodUrl = ""; var hiVodUrl = ""; $.ajax({ url: application.rootUrlPrefix + '/api/getHlsNewsVodUrl', type: "POST", dataType: 'json', data: { vodUrl: lowVod }, success: function (data, status) { if (data && data.success) { lowVodUrl = data.data.streamUrl; self.SD = { file: lowVodUrl, label: '표준화질' } self.init(); } else { lowVodUrl = null; if (data && data.message) { message = data.message; } else { message = 'VOD Url 정보를 가지고 오는데 실패하였습니다.'; } self.init(); } }, error: function (request, status, error) { lowVodUrl = null; message = 'VOD Url 정보를 가지고 오는데 실패하였습니다. >> [' + error + ']'; self.init(); } }); }}/** * 자체영상 (기사 내 영상 여러개, #contentsTag_0, #contentsTag_1 ...) * pip mode 미지원 * fnModSetContentsView 함수에서 tagType(VIDEO, VOD, NEWSVIDEO)에 따라 분류되어 NEWSVIDEO 일 때만 실행 됨 */function _KbsPlayer() { // _KbsPlayer() 에서는 이 부분이 위에 있어야 함 var defaults = { playerWidth: 912, playerHeight: 513, isShortcuts: false, isAutoPlay: false, isCaption: true, vodPlayType: "vod_play_type", mediaFile: [], lowVodUrl: '', highVodUrl: '' }; // jwplayer 기본 설정값 // 함수 arguments와 defaults 값을 가져와 settings에 기본 설정함 this.settings = (arguments[0] && typeof arguments[0] == "object") ? extendDefaults(defaults, arguments[0]) : defaults; if (this.settings.lowVodUrl) { var _lowVodUrl = getKBSHlsVodUrl(this.settings.lowVodUrl); this.SD = { file: _lowVodUrl, label: '표준화질' } } if (this.settings.lowVodUrl != this.settings.highVodUrl) { if (this.settings.highVodUrl) { var _highVodUrl = getKBSHlsVodUrl(this.settings.highVodUrl); this.HD = { file: _highVodUrl, label: '고화질' } } } var self = this; this.init = function () { this.build(); // jwplayer 객체 생성 // jwplayer 최초 렌더링 this.vodPlayer.on("ready", function () { // vod watch log용 변수 설정 self.vodPlayer.$state = 'Z'; self.vodPlayer.$watchTime = 0; self.vodPlayer.$watchStartTime = dayjs(); self.vodPlayer.$watchEndTime = dayjs(); self.preRenderForwardButton(); // 10초 앞으로 버튼 추가 self.preRenderVolumeValueDisplay(); // 볼륨 조절 시 볼륨 값 표시 영역 세팅 self.preRenderKeyboardControl(); // 키보드 조작 이벤트 self.preRenderKeyControlInfo(); // jwplayer에 키보드 컨트롤 안내창 삽입 // 자체 영상에서 세팅 X: 스크롤 내렸을 때 동영상 띄우기 (pip mode) // 자체 영상에서 세팅 X: AutoStart self.preRenderErrorMessage(); // error message (확인필요) }); } this.build = function () { this.vodParams = self.getVodParams(); this.vodPlayer = jwplayer(self.settings.playerId); this.vodPlayer.setup(this.vodParams); // 자동재생 세팅 (_KbsPlayer()에선 자동재생 세팅 안함) // 자막 세팅 var captionYn = isEmptyStr("Y", 'N'); if (captionYn == 'Y') { let captoinClass = (localStorage.getItem("jwplayer.captionLabel") != 'Off') ? 'jw-button-caption on' : 'jw-button-caption'; this.vodPlayer.addButton('', '자막', this.toggleCaption, 'buttonCaption', captoinClass); } this.vodPlayer.on("play", function () { const playerId = self.settings.playerId; $(`#${playerId} .vod-recommed-thumb`).remove(); // 재시작 시 추천동영상 삭제 $(`#${playerId}`).removeClass("jw-state-buffer"); // play 시 buffer 클래스 삭제 $(`#${playerId}`).focus(); // 키보드 조작을 위해 focus clearInterval(jwplayer(playerId).$interval); if(!jwplayer(playerId).$isSeeking) sendVodWatchLog(playerId); jwplayer(playerId).$interval = sendVodWatchLogInterval(playerId); }); // 맨처음 또는 재시작할 때 이벤트, play 이벤트 후 발생 this.vodPlayer.on("firstFrame", function() { // 영어자막 초기설정: playbuttonClicked이 false 일 때만 실행 (play 클릭 시 최초 1회만 실행) // 영어뉴스 일 때는 자막을 항상 켜준다. if( !playbuttonClicked ) { setNewsCaptions(self.vodPlayer); } // play 버튼 클릭 시 true로 바꿔준다. playbuttonClicked = true; }) this.vodPlayer.on("pause", function () { const playerId = self.settings.playerId; clearInterval(jwplayer(playerId).$interval); sendVodWatchLog(playerId); }); this.vodPlayer.on("complete", function () { const playerId = self.settings.playerId; clearInterval(jwplayer(playerId).$interval); sendVodWatchLog(playerId); // 추천동영상 렌더링 getRecommendPlaylist('8346114', res => { displayRecommendPlaylist(res, playerId); }); }); // 재생 바 조작 시 this.vodPlayer.on("seek", function (e) { const playerId = self.settings.playerId; jwplayer(playerId).$seekPosition = e.position; // 현재 재생 위치를 기록 clearInterval(jwplayer(playerId).$interval); let seeking = jwplayer(playerId).$isSeeking; if(seeking === undefined || seeking === false){ jwplayer(playerId).$isSeeking = true; sendVodWatchLog(playerId); } if (!jwplayer(playerId).getConfig().scrubbing) { jwplayer(playerId).$isSeeking = false } // ios safari if( isSafari() ) { setTimeout(() => { if(jwplayer(playerId).getState() == 'playing') { sendVodWatchLog(playerId); } }, 100); } }); // jwplayer 파일 버퍼링일 때 this.vodPlayer.on("buffer", function () { const playerId = self.settings.playerId; $(`#${playerId}`).addClass("jw-state-buffer"); // buffer 클래스 추가 }); } // jwplayer 파라미터 가져오기 this.getVodParams = function () { const isAutoStart = false; // 자체영상에서는 무조건 false const setVolume = localStorage.getItem('jwplayer.volume') ? parseInt(localStorage.getItem('jwplayer.volume')) : 50; var result = { playlist: [{ image: self.settings.imgUrl, sources: [], }], // 자막 style captions: { state: true, color: '#FFFFFF', fontFamily: '"Dotum", "돋움", "Gulim", "굴림"', fontSize: 18, backgroundOpacity: 75, edgeStyle: "uniform" }, // 공유하기 sharing: { link: window.location.href, sites: [ { src: shareFacebook, label: "페이스북" }, { src: shareTwitter, label: "트위터" }, { src: shareKakao, label: "카카오톡" }, { src: shareNaverBlog, label: "네이버블로그" }, { src: shareNaverBand, label: "네이버밴드" }, { src: this.embedVideo, // string과 핸들러 함수로도 사용 가능 label: "동영상 퍼가기" } ] }, playbackRateControls: true, // 재생 속도 컨트롤 활성화 playbackRates: [0.5, 0.8, 1, 1.2, 1.5, 1.8, 2, 3], // 재생 속도 설정 enableShortcuts: this.settings.isShortcuts, // 키보드 단축키 비활성화 autostart: isAutoStart, mute: false, volume: setVolume, aspectratio: '16:9', // 화면 비율 설정 (height 설정 무시 -> height가 없어도 됨) width: this.settings.playerWidth, height: this.settings.playerHeight, repeat: false, // 반복 재생 horizontalVolumeSlider: true, // 사운드바 가로로 controls: true, } var captionYn = isEmptyStr("Y", 'N'); if (captionYn == 'Y') { result.playlist[0].tracks = [{ file: application.rootUrlPrefix + getCaption(), kind: "captions", label: "Korean", default: true }] } if (this.settings.highVodUrl) { result.playlist[0].sources.push(this.HD); } if (this.settings.lowVodUrl) { result.playlist[0].sources.push(this.SD); } return result } // jwplayer에 10초 앞으로 이동 버튼 삽입, 클릭 이벤트 바인딩 this.preRenderForwardButton = function () { const playerId = self.settings.playerId; const HTML = `

    `; $(`#${playerId}`).find(".jw-display-controls.jw-reset").append(HTML); const $forwardButton = $(`#${playerId}`).find(".jw-icon-forward"); $forwardButton.on("click", ()=>{ self.moveForward(); }); } // 볼륨 조절 시 볼륨 값 표시 영역 세팅 this.preRenderVolumeValueDisplay = function () { const playerId = self.settings.playerId; const HTML = `

    `; $(`#${playerId}`).append(HTML); } // 키보드 조작 이벤트 this.preRenderKeyboardControl = function() { document.getElementById(self.settings.playerId).addEventListener('keydown', function (e) { const playerId = self.settings.playerId; const state = jwplayer(playerId).getState(); if (e.keyCode == 37) { // ← self.moveBackward(); e.preventDefault(); } else if (e.keyCode == 39) { // → e.preventDefault(); if (state != 'complete') { self.moveForward(); } } else if (e.keyCode == 38) { // ↑ self.soundUp(); e.preventDefault(); } else if (e.keyCode == 40) { // ↓ self.soundDown(); e.preventDefault(); } else if (e.keyCode == 32) { // spaceBar self.pause(); e.preventDefault(); } else if (e.keyCode == 70) { // f self.fullscreen(); e.preventDefault(); } else if (e.keyCode == 77) { // m self.mute(); e.preventDefault(); } }); } // jwplayer에 키보드 컨트롤 안내창 삽입 this.preRenderKeyControlInfo = function () { const playerId = self.settings.playerId; const HTML = `

    `; $(`#${playerId}`).after(HTML); const $playerWrap = $(`#${playerId}`).parents('.player-wrap'); const $openKeyinfoButton = $playerWrap.find('.button-keyinfo'); const $closeKeyinfoButton = $playerWrap.find('.close-keyinfo'); const $keyinfoBox = $playerWrap.find(".keyinfo-box"); $openKeyinfoButton.on("click", () => $keyinfoBox.toggle()); $closeKeyinfoButton.on("click", () => $keyinfoBox.hide()); } // preRenderErrorMessage (자체 영상에서는 세팅 X) (확인필요) this.preRenderErrorMessage = function() { if (this.vodPlayer.getPlaylist()[0].sources.length == 0) { var errMsg = $(`#${self.settings.playerId}`).find(".error-message"); errMsg.css("display", ""); errMsg.text(message); } } // 영상 재생 10초 뒤로 this.moveBackward = function () { this.moveSeek(-10) } // 영상 재생 10초 앞으로 this.moveForward = function () { this.moveSeek(10); } // 사운드 5포인트 크게 this.soundUp = function () { const playerId = self.settings.playerId; const volume = parseInt(self.vodPlayer.getVolume()); this.moveVolume(5); $(`#${playerId}`).find(".jw-animation.ani-volume").text(`${volume}%`); $(`#${playerId}`).find(".jw-animation.ani-volume").stop(true, true).fadeIn().delay(300).fadeOut(); } // 사운드 5포인트 작게 this.soundDown = function () { const playerId = self.settings.playerId; const volume = parseInt(self.vodPlayer.getVolume()); this.moveVolume(-5); $(`#${playerId}`).find(".jw-animation.ani-volume").text(`${volume}%`); $(`#${playerId}`).find(".jw-animation.ani-volume").stop(true, true).fadeIn().delay(300).fadeOut(); } // 재생 영상 앞으로 뒤로 이동시킴 this.moveSeek = function (sec) { var moveTo = this.vodPlayer.getPosition() + sec if (moveTo < 0) { moveTo = 0 } else if (moveTo > this.vodPlayer.getDuration()) { moveTo = this.vodPlayer.getDuration() } this.vodPlayer.seek(moveTo) } // 사운드 볼륨을 크게 작게 함 this.moveVolume = function (percent) { var volume = this.vodPlayer.getVolume() + percent if (volume < 0) { volume = 0 } else if (volume > 100) { volume = 100 } this.vodPlayer.setVolume(volume) } // 영상 일시 정지하거나 다시 재생시킴 this.pause = function () { const state = this.vodPlayer.getState(); if (state == 'playing') { this.vodPlayer.pause() } else if (state == 'paused' || state == 'complete') { this.vodPlayer.play() } } // 영상 풀스크린으로 보이게 this.fullscreen = function () { if (this.vodPlayer.getFullscreen()) { this.vodPlayer.setFullscreen(false) } else { this.vodPlayer.setFullscreen(true) } } // 음소거 this.mute = function () { if (jwplayer().getMute()) { jwplayer().setMute(false); } else { jwplayer().setMute(true); } } // 자막 보이게 안 보이게 토글 기능 this.toggleCaption = function () { if( self.vodPlayer.getCurrentCaptions() == 0 ) { setCaptionsOn(self.vodPlayer); } else { setCaptionsOff(self.vodPlayer); } } // 영상 자동 재생 토글 toggleAutoStart this.toggleAutoStart = function () { self.settings.isAutoPlay = !self.settings.isAutoPlay; var $autoPlay = $(".jw-button-autostart"); $autoPlay.toggleClass('on'); if ($autoPlay.hasClass('on')) { localStorage.setItem('jwplayer-autoStart', 'true'); } else { localStorage.setItem('jwplayer-autoStart', 'false'); } } // 동영상 퍼가기 (iframe) this.embedVideo = function () { var vod = ''; if (self.settings.highVodUrl) { vod = self.settings.highVodUrl; } else { vod = self.settings.lowVodUrl; } var embedVideoUrl = application.rootUrlPrefix + '/news/pc/view/embedVideo.do?vodUrl=' + vod + '&imgUrl=' + self.settings.imgUrl; var embedUrl = '<iframe width="100%" height="100%" src="' + embedVideoUrl + '" ' + 'title="video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; ' + 'encrypted-media; gyroscope; web-share" allowfullscreen></iframe>'; $('.video-embed-popup .embed-text').html(embedUrl); $('.video-embed-popup').addClass("on"); $('.dim').addClass("on"); $('.body').addClass("on"); $('.header-nav-wrapper').addClass("index-change"); } // 자체영상 에서는 바로 init(); this.init(); this.vodPlayer.play();}// _KbsPlayer 에서 사용function getKBSHlsVodUrl(vodUrl) { if (!vodUrl) { message = 'VOD URL 정보가 없습니다.' return null; } var cdnYn = 'N', duty = 'N', blockingYn = 'N'; if (vodUrl.indexOf('|') == 0) { var vodInfos = vodUrl.split('|'); duty = vodInfos[1]; cdnYn = vodInfos[2]; blockingYn = vodInfos[3]; vodUrl = vodInfos[4]; } cdnYn = 'Y';//무조건 cdn으로 실행 if (duty.indexOf('^') >= 0) { var dutyInfos = duty.split('^'); dutyYn = dutyInfos[0]; if (dutyYn == 'Y') { duty_code = dutyInfos[1]; if (duty_code) { var dutyMsg = ''; $.ajax({ url: application.rootUrlPrefix + '/news/getVodDutyCodeMsg.do', type: "POST", async: false, dataType: 'json', data: { dutyCode: duty_code }, success: function (data, status) { if (data.dutyMsg && data.dutyMsg.resultcode == 1) { dutyMsg = data.dutyMsg.duty_msg; } else { dutyMsg = '저작권 관련 서비스 사용이 불가합니다.'; } }, error: function (request, status, error) { dutyMsg = '저작권 관련 서비스 사용이 불가합니다.'; } }); message = dutyMsg; return null; } } } else { dutyYn = duty; } if (dutyYn == 'Y') { message = '저작권 관련 서비스 사용이 불가합니다.'; return null; } if ("Y" == blockingYn) { var blocking = ''; $.ajax({ url: application.rootUrlPrefix + '/api/getIpInfo', type: "POST", async: false, dataType: 'json', success: function (data, status) { if (data.isAbroadIp) { blocking = data.isAbroadIp; //해외 IP 확인 } }, error: function (request, status, error) { blocking = 'N'; } }); if ("N" == blocking) { message = '저작권 관련 서비스 사용이 불가합니다.'; return; } } // VOD URL 조회 if (!vodUrl) { message = 'VOD URL 정보가 없습니다.'; return null; } if (vodUrl.indexOf("/") == 0) { vodUrl = vodUrl.substr(1); } var hlsUrl = null; if (cdnYn == 'Y') { $.ajax({ url: application.rootUrlPrefix + '/api/getHlsNewsVodUrl', type: "POST", async: false, dataType: 'json', data: { vodUrl: vodUrl }, success: function (data, status) { if (data && data.success) { hlsUrl = data.data.streamUrl; } else { hlsUrl = null; if (data && data.message) { message = data.message; } else { message = 'VOD Url 정보를 가지고 오는데 실패하였습니다.'; } } }, error: function (request, status, error) { hlsUrl = null; message = 'VOD Url 정보를 가지고 오는데 실패하였습니다. >> [' + error + ']'; } }); } return hlsUrl;}// 페이스북 공유function shareFacebook() { var shareUrl = 'https://www.facebook.com/sharer/sharer.php?u=' + encodedCurrentUrl; openPopup(shareUrl);}// 트위터 공유function shareTwitter() { var shareUrl = "https://twitter.com/intent/tweet?url=" + encodedCurrentUrl; openPopup(shareUrl);}// 카카오공유function shareKakao() { var shareDesc = document.getElementById('facebook_desc').getAttribute('content'); var shareImg = document.getElementById('facebook_img').getAttribute('content'); var mShareUrl = currentUrl; Kakao.Link.sendDefault({ objectType: "feed" , content: { title: "KBS News" // 콘텐츠의 타이틀 , description: shareDesc // 콘텐츠 상세설명 , imageUrl: shareImg // 썸네일 이미지 , link: { webUrl: currentUrl, // 모바일 카카오톡에서 사용하는 웹 링크 URL } }, buttons: [ { title: '웹으로 이동', link: { mobileWebUrl: mShareUrl, webUrl: currentUrl }, }, ] }); //sendDefualt}// 네이버블로그 공유function shareNaverBlog() { var shareUrl = 'http://blog.naver.com/openapi/share?url=' + encodedCurrentUrl + '&title='; openPopup(shareUrl);}// 네이버밴드 공유function shareNaverBand() { var shareUrl = "https://band.us/plugin/share?body=" + encodedCurrentUrl + "&route=" + encodedCurrentUrl; openPopup(shareUrl);}// arguments와 defaults의 property를 가져와 속성을 합치는 함수function extendDefaults(defaults, props) { var prop; for (prop in props) { if (props.hasOwnProperty(prop)) { defaults[prop] = props[prop]; } } return defaults;}var sendVodWatchLog = function (playerId) { if (typeof playerId == 'undefined') return; try { const state = jwplayer(playerId).getState(); if (jwplayer(playerId).$state != 'B') { switch (state) { case 'playing': jwplayer(playerId).$state = 'S'; // play break; case 'paused': jwplayer(playerId).$state = 'P'; // paused break; case 'complete': jwplayer(playerId).$state = 'C'; // complete break; default: jwplayer(playerId).$state = 'Z'; // etc break; } // seek if(jwplayer(playerId).$isSeeking) { jwplayer(playerId).$state = 'M' } } // watchStartTime if( jwplayer(playerId).$state == 'S' ) { jwplayer(playerId).$watchStartTime = dayjs(); } // watchEndTime jwplayer(playerId).$watchEndTime = dayjs(); let gapTime = dayjs.duration(jwplayer(playerId).$watchEndTime.diff(jwplayer(playerId).$watchStartTime)).asMilliseconds() * 0.001; // 재생시간이 늘어나지 않는 경우 ('P || M -> *') if(jwplayer(playerId).$beforeState == 'P' || jwplayer(playerId).$beforeState == 'M') { gapTime = 0; } jwplayer(playerId).$watchTime += gapTime; // param2: 선택한 영상의 총 재생시간 // param3: 선택한 영상의 재생 위치 (M 일 때는 마지막 시청위치) // param12: 선택한 영상의 mediasetSeq var param2 = Math.floor(jwplayer(playerId).getDuration()); var param3 = (jwplayer(playerId).$state == 'M') ? Math.floor(jwplayer(playerId).$seekPosition) : Math.floor(jwplayer(playerId).getPosition()); var param12 = getParam12(playerId); var sendWatchTime = Math.floor(jwplayer(playerId).$watchTime); var sendState = jwplayer(playerId).$state; // console.log('watch', 'VOD', param2, param3, param4, '', sendWatchTime, sendState, '', '', '', '', param12, param13); window._add_rte('watch', 'VOD', param2, param3, param4, '', sendWatchTime, sendState, '', '', '', '', param12, param13); // beforeState update jwplayer(playerId).$beforeState = jwplayer(playerId).$state; } catch (e) { // 새로고침 시 플레이어가 생성되기 전 발생 console.error('sendVodWatchLog : ', e.message); }};var sendVodWatchLogInterval = function (playerId) { // param2: 선택한 영상의 총 재생시간 // param12: 선택한 영상의 mediasetSeq var param2 = Math.floor(jwplayer(playerId).getDuration()); var param12 = getParam12(playerId); // setInterval var id = setInterval(function () { // param3: 선택한 영상의 재생 위치 갱신 var param3 = Math.floor(jwplayer(playerId).getPosition()); // watchtime jwplayer(playerId).$watchStartTime = dayjs(); // $watchStartTime도 함께 갱신 해준다. jwplayer(playerId).$watchEndTime = dayjs(); // $watchEndTime도 함께 갱신 해준다. jwplayer(playerId).$watchTime += (logIntervalTime/1000); var sendWatchTime = Math.floor(jwplayer(playerId).$watchTime); var sendState = jwplayer(playerId).$state; // console.log('watch', 'VOD', param2, param3, param4, '', sendWatchTime, sendState, '', '', '', '', param12, param13); window._add_rte('watch', 'VOD', param2, param3, param4, '', sendWatchTime, sendState, '', '', '', '', param12, param13); }, logIntervalTime); return id;}// param12: 선택한 영상의 mediasetSeq (영상의 순서, 1부터 시작)function getParam12(playerId) { // mediasetSeq는 playerId에서 가져올 수 있다. // 대표영상일 경우 mediasetSeq: playerId: playerElement // 자체영상일 경우 mediasetSeq: player_contentsTag_0 ~ ... (+1 해서 1부터 사용) if ( playerId.includes('player_') ) { // 자체영상 일 경우 return param12 = playerId.split('_')[2] * 1 + 1; } return 1;}// 자막 파일 가져오기function getCaption() { var captionUrl = ""; var srtUrl = ""; var lowVod = isEmptyStr("/newsmp4/newsplaza/2025/09/02/500k/260_8346114.mp4", "/newsmp4/newsplaza/2025/09/02/1500k/260_8346114.mp4"); var captionYn = isEmptyStr("Y", 'N'); var arrUrl = lowVod.split('|'); srtUrl = arrUrl[arrUrl.length - 1].replace('.mp4', '.srt'); if (captionYn == "Y") { captionUrl = '/data/srt/FIXED' + srtUrl } else { captionUrl = null } captionUrl = (captionUrl == null) ? "/resource/image/mobile/player/myFilevtt.vtt" : captionUrl; return captionUrl;}// 추천동영상용 데이터 가져오기function getRecommendPlaylist(param, successCallback, errorCallback) { return $.ajax({ url: application.rootUrlPrefix + '/api/getRecommendVod?newsCode=' + param, type: "POST", dataType: 'json', data: param, success: successCallback, error: errorCallback });}// 추천동영상 DOM 렌더링function displayRecommendPlaylist (res, playerId) { var data = []; if (res.data.length == 0) { return; } if (res && res.data.length > 0) { data = res.data; } var length = 4; for (var i = 0; i < length; i++) { var $thumb = $('').clone(); var $title = $(''); var $p = $('

    '); $thumb.css('background-image', 'url(' + application.rootUrlPrefix + data[i].imgUrl + ')'); $thumb.addClass('recommed-' + i); $thumb.attr('href', data[i].url); var title = (data[i].title).replace(/
    /g, ''); $title.css('display', 'flex'); $p.text(title); $title.append($p); $thumb.append($title); $(`#${playerId}`).append($thumb); }}// 영어뉴스일 경우 true를 반환환다.function isEngNews() { const sourceCode = "200" return (sourceCode == "172") ? true : false;}// 영어뉴스일 경우: html에 data-news-lang="en"을 추가한다.function setEngNews() { if (!isEngNews()) return; $("html").attr("data-news-lang", "en");}// 영어뉴스 자막 초기설정function setNewsCaptions(vodPlayer) { if( isEngNews() ) setCaptionsOn(vodPlayer); setCaptionsIcon(vodPlayer);}// 자막 켜기function setCaptionsOn(vodPlayer) { vodPlayer.setCurrentCaptions(1); setCaptionsIcon(vodPlayer);}// 자막 끄기function setCaptionsOff(vodPlayer) { vodPlayer.setCurrentCaptions(0); setCaptionsIcon(vodPlayer);}// 자막 켜기/끄기 아이콘function setCaptionsIcon(vodPlayer) { const currentPlayer = $(`#${vodPlayer.id}`); if( vodPlayer.getCurrentCaptions() == '0' ) { currentPlayer.find(".jw-button-caption").removeClass('on'); } else { currentPlayer.find(".jw-button-caption").addClass('on'); }}// ios safari checkfunction isSafari() { return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);}// error messagefunction displayErrorMessage(playerId, message) { $(`#${playerId}`).parents(".player-app").find(".error-message").html(message).show();}

    이전 슈카 ‘990원 소금빵’ 논란…자영업자들 뿔났다? 굿바이 ‘쎄시봉’…57년 만에 뭉쳐 ‘고별 무대’ 다음

    [앵커]

    요즘 식당에 가면 사람 대신 음식을 가져다주는 로봇은 흔하게 볼 수 있죠.

    이젠 실내뿐만 아니라 실외에서도 자율주행 배달 로봇이 속속 도입되고 있는데요.

    도심 공원에까지 커피를 배달해 주는 로봇도 등장했습니다.

    김하은 기자입니다.

    [리포트]

    한 카페 앞에 멈춰 선 자율주행 로봇, 주문받은 커피가 실리자마자, 부지런히 배달에 나섭니다.

    횡단보도 앞에서는 사람처럼 멈췄다 출발하고, 장애물이 나타나면 안전하게 피해 갑니다.

    ["물품을 배송 중입니다. 조심히 지나갈게요."]

    서울 양천구의 공원 3곳에서 시범 운행을 시작한 자율주행 배달 로봇입니다.

    별도 앱을 통해 주문하면 배달비 부담 없이 커피 한 잔도 주문할 수 있습니다.

    [김정운/서울 양천구 : "재밌을 것 같아요. 더 편하게 이제 앉아서 기다리는 그런 것도 있고 공원에서 커피숍 온 것 같은 기분(이 들 거 같습니다)."]

    배달 수수료가 없어 점주 입장에서도 부담이 적습니다.

    [안정민/'로봇 배달' 서비스 이용업주 : "수수료적인 거나 손님들이 오지 못하는 경우에도 저희는 전달을 해드릴 수 있기 때문에 매출적으로도 더 도움이 되지 않을까…"]

    이 로봇은 이미 해당 공원에서 다른 용도로도 사용돼 왔습니다.

    내장된 렌즈를 이용해 취약 시간대 공원 순찰 업무는 물론, 공원 이용객들을 위한 쓰레기 분리수거 업무도 가능합니다.

    ["재활용품을 수거하고 있습니다. 잠시 비켜주세요."]

    [전인호/로봇 개발 업체 매니저 : "주행(기술)이 많이 안정화가 돼 있습니다. 앞으로는 공원, 주거지, 상가 등등을 연계하는 생활권형 로봇 서비스를 확장할 계획입니다."]

    발전하는 로봇 기술들로 각종 자율주행 로봇들이 일상의 풍경 속에 자연스럽게 자리 잡고 있습니다.

    KBS 뉴스 김하은입니다.

    촬영기자:하정현/영상편집:이현모

    ■ 제보하기
    ▷ 카카오톡 : 'KBS제보' 검색, 채널 추가
    ▷ 전화 : 02-781-1234, 4444
    ▷ 이메일 : kbs1234@kbs.co.kr
    ▷ 유튜브, 네이버, 카카오에서도 KBS뉴스를 구독해주세요!

    • 공원에 웬 로봇이…커피 배달도 ‘척척’
      • 입력 2025-09-02 08:01:23
      • 수정2025-09-02 08:05:56
      뉴스광장

    공원에 웬 로봇이…커피 배달도 ‘척척’ (7)

    [앵커]

    요즘 식당에 가면 사람 대신 음식을 가져다주는 로봇은 흔하게 볼 수 있죠.

    이젠 실내뿐만 아니라 실외에서도 자율주행 배달 로봇이 속속 도입되고 있는데요.

    도심 공원에까지 커피를 배달해 주는 로봇도 등장했습니다.

    김하은 기자입니다.

    [리포트]

    한 카페 앞에 멈춰 선 자율주행 로봇, 주문받은 커피가 실리자마자, 부지런히 배달에 나섭니다.

    횡단보도 앞에서는 사람처럼 멈췄다 출발하고, 장애물이 나타나면 안전하게 피해 갑니다.

    ["물품을 배송 중입니다. 조심히 지나갈게요."]

    서울 양천구의 공원 3곳에서 시범 운행을 시작한 자율주행 배달 로봇입니다.

    별도 앱을 통해 주문하면 배달비 부담 없이 커피 한 잔도 주문할 수 있습니다.

    [김정운/서울 양천구 : "재밌을 것 같아요. 더 편하게 이제 앉아서 기다리는 그런 것도 있고 공원에서 커피숍 온 것 같은 기분(이 들 거 같습니다)."]

    배달 수수료가 없어 점주 입장에서도 부담이 적습니다.

    [안정민/'로봇 배달' 서비스 이용업주 : "수수료적인 거나 손님들이 오지 못하는 경우에도 저희는 전달을 해드릴 수 있기 때문에 매출적으로도 더 도움이 되지 않을까…"]

    이 로봇은 이미 해당 공원에서 다른 용도로도 사용돼 왔습니다.

    내장된 렌즈를 이용해 취약 시간대 공원 순찰 업무는 물론, 공원 이용객들을 위한 쓰레기 분리수거 업무도 가능합니다.

    ["재활용품을 수거하고 있습니다. 잠시 비켜주세요."]

    [전인호/로봇 개발 업체 매니저 : "주행(기술)이 많이 안정화가 돼 있습니다. 앞으로는 공원, 주거지, 상가 등등을 연계하는 생활권형 로봇 서비스를 확장할 계획입니다."]

    발전하는 로봇 기술들로 각종 자율주행 로봇들이 일상의 풍경 속에 자연스럽게 자리 잡고 있습니다.

    KBS 뉴스 김하은입니다.

    촬영기자:하정현/영상편집:이현모

    • 공원에 웬 로봇이…커피 배달도 ‘척척’ (8)

      김하은 hani@kbs.co.kr

      김하은의 기사 모음

    공원에 웬 로봇이…커피 배달도 ‘척척’ (9)

    김하은

    이 기사가 좋으셨다면

    • 좋아요

    • 응원해요

    • 후속 원해요

    오늘의 핫 클릭

    실시간 뜨거운 관심을 받고 있는 뉴스

    이 기사에 대한 의견을 남겨주세요.

    헤드라인

    천안문 망루에 김정은-시진핑-푸틴 나란히…김정은에 최고 수준 예우 트럼프 “반미 모의…푸틴·김정은에 안부 전해달라” [단독] 통일교 전관 변호인 “민중기 특검 직접 만났다”…‘특검 원칙’ 위배 피자 가게서 주인이 흉기 휘둘러 3명 사망…“인테리어 갈등”

    많이 본 뉴스

    각 플랫폼에서 최근 1시간 동안 많이 본
    KBS 기사를 제공합니다.

      • 1 서울 관악구 조원동서 ‘흉기 난동’…3명 사망·1명 중상
      • 2 “추 대표, 걱정마라”…공소장 속 한덕수 ‘계엄 보좌’ 정황들
      • 3 폐암으로 숨진 유치원 조리실무사 첫 순직 인정
      • 4 “마늘 두 시간 까면 만5천 원”…대기까지 치열하다는 일거리 뭐기에?
      • 5 1분 만에 300도 치솟아…스프링클러도 무용지물
      • 6 베일 벗은 중국 ‘비장의 핵무기’…“육해공 어디서건 쏠 수 있다”

    요약내용

    요약 내용은 네이버 및 OpenAI 社의 AI 서비스를 통해 제공하고 있습니다.
    기사의 내용을 올바르게 이해하기 위해서는 본문을 함께 읽어야 합니다.

    동영상 퍼가기

    KBS 뉴스 사이트 동영상을 퍼가면 KBS 뉴스의 서비스
    이용정책에 동의하는 것으로 간주합니다.

    공원에 웬 로봇이…커피 배달도 ‘척척’ (2025)
    Top Articles
    Latest Posts
    Recommended Articles
    Article information

    Author: Ouida Strosin DO

    Last Updated:

    Views: 6410

    Rating: 4.6 / 5 (76 voted)

    Reviews: 83% of readers found this page helpful

    Author information

    Name: Ouida Strosin DO

    Birthday: 1995-04-27

    Address: Suite 927 930 Kilback Radial, Candidaville, TN 87795

    Phone: +8561498978366

    Job: Legacy Manufacturing Specialist

    Hobby: Singing, Mountain biking, Water sports, Water sports, Taxidermy, Polo, Pet

    Introduction: My name is Ouida Strosin DO, I am a precious, combative, spotless, modern, spotless, beautiful, precious person who loves writing and wants to share my knowledge and understanding with you.