다음을 통해 공유


빠른 시작: 원격 재생 기능을 사용하여 슬라이드 쇼 스트리밍(HTML)

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

원격 재생 기능을 사용하면 사용자가 컴퓨터의 오디오, 동영상 또는 이미지를 홈 네트워크의 장치로 쉽게 스트리밍할 수 있습니다. 이 항목에서는 Windows 스토어 앱에서 원격 재생 기능을 사용하여 사용자가 이미지를 대상 장치에 슬라이드 쇼로 스트리밍할 수 있도록 하는 방법을 보여 줍니다.

목표: 원격 재생 기능을 사용하여 이미지를 대상 장치에 슬라이드 쇼로 스트리밍합니다.

사전 요구 사항

Microsoft Visual Studio

지침

1. 새 프로젝트 만들기 및 사진에 액세스할 수 있도록 설정

  1. Visual Studio를 열고 파일 메뉴에서 새 프로젝트를 선택합니다. Javascript 섹션에서 새 응용 프로그램을 선택합니다. 응용 프로그램의 이름을 PlayToSlideShow로 지정하고 확인을 클릭합니다.
  2. Package.appxmanifest 파일을 열고 기능 탭을 선택합니다. 사진 라이브러리 기능을 선택하여 응용 프로그램이 컴퓨터의 사진 폴더에 액세스할 수 있게 합니다. 매니페스트 파일을 저장하고 닫습니다.

2. HTML UI 추가

Default.html 파일을 열고 다음 HTML을 <body> 섹션에 추가합니다. UI에는 이미지를 표시하는 데 사용되는 <div>와 상태 메시지를 표시하는 데 사용되는 태그가 포함되어 있습니다. 또한 UI에는 원격 재생 기능을 사용하여 스트리밍을 시작하는 방법을 알려 주는 <div>와 스트리밍할 때 연결을 끊을 수 있는 단추도 포함되어 있습니다. 이러한 두 요소는 슬라이드 쇼가 스트리밍되고 있는지 여부에 따라 숨겨지거나 표시됩니다.

<div id="slideshowDiv" style="height:600px;display:table-cell;vertical-align:bottom;"></div>
<div id="messageDiv">Slideshow disconnected</div>
<button id="disconnectButton" style="width:600px;height:60px;display: none">
    Connected to <img id="iconImage" style="width: 30px;" /> <span id="deviceSpan" />
</button>
<div id="instructionsDiv">Swipe from the right edge of the screen, select "Devices", and select a device to stream the slide show to.</div>

3. 초기화 코드 추가

이 단계의 코드에서는 슬라이드 쇼를 시작하고 연결 끊기 단추 클릭 이벤트의 처리기를 만듭니다. 이 코드에는 getElementById 함수에 간편하게 액세스하기 위한 바로 가기 함수 id도 포함됩니다.

js 폴더를 엽니다. Default.js 파일을 열고 다음 코드를 기본 onactivated 함수 대신 추가합니다.

app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {

        startSlideShow();

        args.setPromise(WinJS.UI.processAll());
    }
};

// Disconnect button event handler.
function disconnectButtonClick() {
    Windows.Media.PlayTo.PlayToManager.showPlayToUI();
}

// Shortcut function.
function id(tagName) {
    return document.getElementById(tagName);
}

4. 이미지를 가져와 슬라이드 쇼로 표시하는 코드 추가

이 샘플은 사진 루트 폴더에 있는 이미지를 사용하여 이미지를 슬라이드 쇼로 표시합니다. 이를 위해 우선 사진에서 이미지 목록을 가져온 다음 <image> 개체를 만들어 목록을 순환합니다.

원격 재생을 사용하여 이미지를 스트리밍할 때 이 슬라이드 쇼의 코드는 원격 재생을 사용하여 다음 미디어 항목을 버퍼링하는 기능을 사용합니다. 이 기능은 옵션이지만 스트리밍할 다음 미디어 항목을 가져오는 데 추가 시간이 걸리는 경우 유용합니다. 미디어를 버퍼링하면 현재 미디어 항목이 완료된 후 즉시 스트림하여 미디어 항목 간의 지연을 방지할 수 있습니다.

다음 미디어 항목을 버퍼링하기 위해 다음 항목의 재생 원본을 현재 항목의 next 속성으로 설정합니다. 현재 항목이 완료되면 현재 항목의 playNext 메서드를 호출하여 다음 미디어 원본을 대상 장치로 스트리밍합니다.

슬라이드 쇼가 로컬에서만 재생되는 경우 코드에서는 시간 제한을 사용하여 목록의 다음 이미지로 이동합니다. 슬라이드 쇼가 원격 재생 수신기로 스트리밍되는 경우에는 코드에서 여전히 시간 제한을 사용하여 다음 이미지로 이동하지만 원격 재생 수신기가 슬라이드 쇼를 일시 중지하거나, 시간 제한이 만료되기 전에 다음 이미지로 이동하거나, 연결이 끊긴 경우에도 응답합니다. 이를 위해 이미지 개체의 msPlayToSource 속성에서 참조되는 원격 재생 원본의 statechanged 이벤트를 사용합니다. statechanged 이벤트에서 코드는 이벤트에 전달된 인수의 currentStatepreviousState 속성을 검사합니다. 다음 표에 나온 대로 상태 및 statechanged 이벤트를 발생시킨 이미지의 인덱스를 식별하는 번호에 따라 응답하는 방법이 다릅니다.

currentState 수행할 작업
disconnected

이벤트를 발생시킨 이미지의 인덱스가 현재 표시되고 있는 이미지의 인덱스와 동일한 경우 이미지가 표시되고 있는 동안 원격 재생 원본의 연결이 끊긴 것입니다. 따라서 원격 재생 수신기가 더 이상 연결되어 있지 않으며 슬라이드 쇼가 이미지 인덱스를 사용하여 로컬에서 시작됩니다. 그렇지 않은 경우 disconnected 상태는 슬라이드 쇼에서 이벤트를 발생시킨 이미지 표시가 완료되었음을 나타내므로 더 이상 필요하지 않은 이미지 개체를 정리할 수 있습니다.

connected

이전 상태가 disconnected인 경우 이벤트를 발생시킨 이미지가 원격 재생 수신기에 방금 연결된 것입니다. 이제 현재 이미지가 표시되어 있는 동안 로드되도록 다음 이미지를 가져옵니다.

이전 상태가 rendering인 경우 사용자가 원격 재생 수신기에서 슬라이드 쇼를 일시 중지한 것이므로 사용자가 쇼를 다시 시작할 때까지 현재 시간 제한을 지웁니다.

rendering 이전 상태가 connected인 경우 원격 재생 수신기가 슬라이드 쇼를 일시 중지하지 않은 것이므로 쇼를 다시 시작할 수 있습니다.

 

Default.js 파일에서 이전 단계의 코드 뒤에 다음 코드를 추가합니다.

var states = Windows.Media.PlayTo.PlayToConnectionState, // alias for PlayToConnectionState
    imageList,               // contains the list of images to show
    streaming = false,       // true when streaming using Play To; otherwise false
    cancel = 0,              // used to cancel a timeout
    timeLapse = 5,           // time between images (5 seconds)
    imageSize = "600px",     // size of current displayed image
    thumbnailSize = "200px", // size of "thumbnail" of next image
    currentImage = 0;        // index of the current image from imageList

// Get the list of images from the Pictures folder and start the slide show.

function startSlideShow() {
    Windows.Storage.KnownFolders.picturesLibrary.getFilesAsync().then(
        function (resultsLibrary) {
            imageList = resultsLibrary;
            if (imageList.length > 0) {
                var image = queueImage(0, true);
            } else {
                id("messageDiv").innerHTML = "There are no images in the Pictures library.";
            }
        });
}


// playNextImage
// Called when a new image is displayed due to a timeout.
// Removes the current image object and queues a new next image.
// Sets the next image index as the new current image, and increases the size 
// of the new current image. Then sets the timeout to display the next image.

function playNextImage(num) {
    id("slideshowDiv").removeChild(id("image" + num));
    queueImage(num + 2, false);

    currentImage = num + 1;
    id("image" + currentImage).style.width = imageSize;

    cancel = setTimeout(function () {
        playNextImage(num + 1);
    }, timeLapse * 1000);
}


// queueImage
// Called to create an image object for the displayed images.

function queueImage(num, isFirstImage) {

    // Create the image element for the specified image index and add to the
    // slide show div.

    var image = document.createElement("img");
    image.style.width = (isFirstImage ? imageSize : thumbnailSize);
    image.id = "image" + num;
    image.src = URL.createObjectURL(imageList[num % imageList.length], { oneTimeOnly: true });
    id("slideshowDiv").appendChild(image);

    // If this is the first image of the slide show, queue the next image. Do
    // not queue if streaming as images are already queued before
    // streaming using Play To.

    if (isFirstImage && !streaming) {

        queueImage(num + 1, false);

        cancel = setTimeout(function () {
            playNextImage(num);
        }, timeLapse * 1000);            
    }

    // Use the transferred event of the Play To connection for the current image object
    // to "move" to the next image in the slide show. The transferred event occurs
    // when the PlayToSource.playNext() method is called, or when the Play To
    // Receiver selects the next image.

    image.msPlayToSource.connection.addEventListener("transferred", function () {

        currentImage = num + 1;
        id("image" + currentImage).style.width = imageSize;

    }, false);


    // Use the statechanged event to determine which action to take or to respond
    // if the Play To Receiver is disconnected.
    image.msPlayToSource.connection.addEventListener("statechanged", function (e) {

        switch (e.currentState) {
            case states.disconnected:

                // If the state is disconnected and the current image index equals the 
                // num value passed to queueImage, then the image element is not connected 
                // to the Play To Receiver any more. Restart the slide show.
                // Otherwise, the current image has been discarded and the slide show
                // has moved to the next image. Clear the current image object and
                // remove it from the slide show div.

                if (currentImage == num) {
                    id("messageDiv").innerHTML = "Slideshow disconnected";

                    // Cancel any existing timeout
                    if (cancel) {
                        clearTimeout(cancel);
                    }

                    // Clear all image objects from the slide show div
                    while (id("slideshowDiv").firstChild) {
                        id("slideshowDiv").removeChild(id("slideshowDiv").firstChild);
                    }

                    // Reset the slide show objects and values to their beginning state
                    streaming = false;
                    id("disconnectButton").style.display = "none";
                    id("instructionsDiv").style.display = "block";
                    disconnectButton.removeEventListener("click", disconnectButtonClick, false);

                    // Restart the slide show from the current image index
                    queueImage(currentImage, true);
                } else {
                    image.msPlayToSource.next = null;
                    image.removeAttribute("src");

                    if (streaming) {
                        id("slideshowDiv").removeChild(image);
                    }
                }

                break;
                
            case states.connected:

                // If the state is connected and the previous state is disconnected, 
                // then the image element is newly connected. Queue up the next image so 
                // that it is loaded while the current image is being displayed.
                // If the previous state is rendering, then the user has paused the slideshow 
                // on the Play To Receiver. Clear the current timeout until the user restarts
                // the slide show.

                if (e.previousState === states.disconnected) {
                    var imageNext = queueImage(num + 1, false);
                    image.msPlayToSource.next = imageNext.msPlayToSource;
                } else if (e.previousState === states.rendering) {
                    if (cancel) {
                        clearTimeout(cancel);
                        cancel = 0;
                    }
                }

                if (currentImage == num) {
                    id("messageDiv").innerHTML = "Slideshow connected";
                }

                break;

            case states.rendering:

                // If the state is rendering and the previous state is
                // connected, then the Play To Receiver has restarted
                // the slide show.

                if (e.previousState === states.connected) {

                    // Clear any existing timeout.
                    if (cancel) {
                        clearTimeout(cancel);
                    }

                    // Restart the slide show.
                    cancel = setTimeout(function () {
                        image.msPlayToSource.playNext();
                    }, timeLapse * 1000);
                }

                if (currentImage == num) {
                    id("messageDiv").innerHTML = "Slideshow rendering";
                }

                break;
        }

    }, false);

    return image;
}

5. 재생 코드 추가

이 단계의 코드는 재생 계약을 구현합니다. 현재 응용 프로그램의 PlayToManager에 대한 참조를 가져오고 sourcerequestedsourceselected 이벤트의 이벤트 처리기를 연결합니다.

슬라이드 쇼의 각 이미지에 대해 이미지 개체를 만들고 삭제하므로 sourcerequested 이벤트에서는 삭제되지 않는 임시 이미지 개체를 사용합니다. 이는 사용자가 원격 재생 수신기를 선택하기 전에 시간 제한이 만료될지 모르기 때문입니다. 그럴 경우 현재 이미지가 삭제되므로 원격 재생에 null 참조를 전달합니다. 대신 삭제되지 않는 이미지 개체에 원격 재생 참조를 전달하고 사용자가 원격 재생 수신기를 선택하면 이미지 원본을 현재 표시된 이미지로 업데이트합니다. 이것은 이미지 상태가 connected로 변경될 때 발생했습니다.

Default.js 파일에서 이전 단계의 코드 뒤에 다음 코드를 추가합니다.

// Set up the Play To contract.

// Used to pass an image to Play To that will not be removed/destroyed
// by the slide show logic. For example, if the user opens the Devices
// charm and the sourcerequested event fires, but the image display timeout
// completes before the user selects a target device, then the image that
// was being displayed is removed and destroyed. intialImage is never 
// destroyed so Play To will always have a valid source to stream.
var initialImage = null;

var ptm = Windows.Media.PlayTo.PlayToManager.getForCurrentView();

ptm.addEventListener("sourcerequested", function (e) {
    initialImage = document.createElement("img");

    // Use the statechanged event of the image passed to Play To to determine when
    // the image is finally connected to the Play To Receiver.
    initialImage.msPlayToSource.connection.addEventListener("statechanged", function (e) {

        if (e.currentState === states.connected) {

            // Clear any existing timeout.
            if (cancel) {
                clearTimeout(cancel);
                cancel = 0;
            }

            // Clear the slide show div.
            while (id("slideshowDiv").firstChild) {
                id("slideshowDiv").removeChild(id("slideshowDiv").firstChild);
            }

            // Set the slide show objects and values to show that we are streaming.
            streaming = true;
            id("disconnectButton").style.display = "block";
            id("instructionsDiv").style.display = "none";

            // Queue and display the next image.
            var image = queueImage(currentImage, true);
            initialImage.msPlayToSource.next = image.msPlayToSource;
            initialImage.msPlayToSource.playNext();
        }
    }, false);

    // Provide Play To with the first image to stream.
    e.sourceRequest.setSource(initialImage.msPlayToSource);

}, false);

// Update the once the user has selected a device to stream to.
ptm.addEventListener("sourceselected", function (e) {
    disconnectButton.addEventListener("click", disconnectButtonClick, false);
    id("messageDiv").innerHTML = "Streaming to " + e.friendlyName + "...";
    id("deviceSpan").innerHTML = e.friendlyName + ".<br/>Click here to disconnect.";
    id("iconImage").src = URL.createObjectURL(e.icon, { oneTimeOnly: true });
}, false);

6. 재생 대상 만들기(옵션)

응용 프로그램을 실행하려면 원격 재생 기능이 미디어를 스트리밍할 수 있는 대상 장치가 필요합니다. 인증된 원격 재생 수신기가 없는 경우 Windows Media Player를 대상 장치로 사용할 수 있습니다. Windows Media Player를 대상 장치로 사용하려면 컴퓨터가 개인 네트워크에 연결되어 있어야 합니다. Windows Media Player가 원격 재생 원본 앱과 다른 컴퓨터에서 실행되고 있어야 합니다.

  1. Windows Media Player를 시작합니다.
  2. 스트림 메뉴를 확장하고 내 플레이어 원격 제어 허용... 옵션을 사용하도록 설정합니다. Windows Media Player를 열어 둡니다. 실행되고 있어야 재생 대상으로 사용할 수 있습니다.
  3. 장치 및 프린터 제어판을 엽니다. 장치 및 프린터 추가를 클릭합니다. 장치 및 프린터 추가 마법사의 이 PC에 추가할 장치 또는 프린터 선택 창에서 사용자 PC의 디지털 미디어 렌더러를 찾습니다. 이것이 사용자 PC의 Windows Media Player입니다. 선택하고 다음을 클릭합니다. 마법사가 완료되면 멀티미디어 장치 목록에 Windows Media Player 인스턴스가 표시됩니다.

7. 앱 실행

  • Visual Studio에서 F5(디버그) 키를 눌러 앱을 실행합니다. 미디어 단추 중 하나를 선택하여 다른 미디어 라이브러리에 있는 첫 번째 미디어 항목을 재생하거나 볼 수 있습니다. 미디어가 재생되는 동안 장치 참 메뉴를 열고 재생 대상을 선택하여 미디어를 대상 장치로 스트리밍합니다.

요약

이 빠른 시작에서는 이미지를 대상 장치에 슬라이드 쇼로 표시하는 원격 재생 기능을 응용 프로그램에 추가했습니다. 원격 재생 기능을 사용하여 응용 프로그램의 콘텐츠를 네트워크의 인증된 원격 재생 수신기로 스트리밍할 수 있습니다.

관련 항목

원격 재생을 사용하여 장치로 미디어 스트리밍

예제

재생 샘플

PlayToReceiver 샘플

미디어 서버 샘플