소스라이브 플레이어 V1.0.0

1. 소개

라이브 URL로 접근했을 때 보여지는 페이지이며, 라이브를 시청할 수 있습니다.

라이브 전에는 편성표로 이동하고, 라이브가 시작되었다면 바로 플레이어로 이동합니다.

위 경우에 대한 소스라이브 플레이어에 대한 가이드 입니다.


2-1. 연동 방법

두 가지 경우에 대해서 고려할 수 있습니다.

  • 라이브가 종료된 경우
  • 로그인이 필요한 경우

자사몰에 연동하는 경우는 아래 JSON필드 예시 내용을 참고하고 소스라이브 개발팀으로 관련 내용 전달해 주세요.

라이브 입장

  • 기본 동작은 없습니다.
  • 공유하기

공유하기

  • 사용 여부의 기본은 사용으로 되어있습니다.
  • 파트너사 자체 앱 공유하기를 사용할 경우 스킴을 통해 제목,주소(playerURL), 라이브 대표 이미지
  • SNS기능을 사용하지 않는 경우, 주소 복사하기만 가능합니다

쿠폰기능

  • 사용여부 기본은 미사용으로 되어있습니다.

방송닫기 URL

  • 기본 동작은 history.back() 입니다.

⭐️ stage, prod 환경 설정 적용 - 궁금한 내용은 카카오톡, 채널톡 또는 담당자 이메일 [email protected] 문의

{
      /* 방송입장 관련 */
      "enter":{
           /* 웹뷰스킴 호출 */
           /* Type string|string[]|null defaultValue:null */
           /* 적용예시)"webivew":"sauceflexapp://enter"*/
           "webview":null
      },
      /* 공유하기 관련 */
      "share":{
           /* 공유하기 사용여부 */
           /* Type boolean defaultVlue:true */
           "use":true,
 
           /* 공유하기 눌렀을시 웹뷰스킴 호출 제목, 방송주소, 대표이미지를 encodeURIComponent 하여 json 파라미터로 넘겨줍니다. */
           /* Type string | null defaultValue:null */
           /* 적용예시) "webview":"sauceflexapp://share?${JSON}"
              JSON에는 제목, 방송주소, 대표이미지 encodeURIComponent 하여 json 파라미터
           */
           "webview":null,
 
           /* sns사용 여부 */
           /* Type boolean defaultVlue true*/
           "sns":true
 
           /* 카카오공유 앱 호출링크 */
           /* Type string | null defaultValue null*/
           "kakaoAppLink":null
       },
 
      /* 쿠폰기능 관련 */
      "coupon": {
           /* 쿠폰기능 사용여부 */
           /* Type boolean defaultValue true */
           "use":true,
       },
 
      /* 비회원 관련 */
      "guestLogin":{
            /* 비회원 로그인 사용여부 (회원 or 비회원 택1)*/
            /* Type boolean defaultValue false*/
            "use":false,
           
            /* 비회원 로그인 개인정보 수집 약관 주소 */
            /* Type string|null defaultValue null*/
            "agreementUrl":null
      },
 
      /* 페이지 이동관련 */
      "redirection":{
           /* 로그인관련 */
           "login": {
                /* 웹뷰스킴 호출 */
                /* Type string | null defaultValue null */
                /* 적용 예시) "webivew":"sauceflexapp://login" */
                "webview":null,
 
                /* 히스토리 방법 */
                /* Type "href" | "replace"  defaultValue "href" href= "히스토리 추가되어 동작",replace="현재 페이지 히스토리를 변경" */
                "history": "href",
 
                /* 모바일주소 */
                /* Type string | null defaultVlue null*/
                /* 예시) "https://stage.space.sauceflex.com/?returnUrl=${broadcastUrl}"  */
                "mobile": null,
 
                /* 피씨주소 */
                /* Type string | null */
                /* 예시) "https://stage.space.sauceflex.com/?returnUrl=${broadcastUrl}" */            
                "pc": null
            },
           /* 닫기버튼 관련(❌ 뒤로가기와 다르게 동작합니다.) */
           "broadcastClose": {
                /* 웹뷰스킴 호출 */
                /* Type string | null */
                /* 적용 예시) "webivew":"sauceflexapp://close" */
                "webview":null,
 
                /* 히스토리 방법 */                
                /* Type "href" | "replace" defaultValue "href" href= "히스토리 추가되어 동작",replace="현재 페이지 히스토리를 변경" */
                "history": "href",
 
                /* 모바일주소 */
                /* Type string | null defaultValue null*/
                /* 예시) "https://stage.space.sauceflex.com/?returnUrl=${broadcastUrl}"*/
                "mobile": null,
 
                /* 피씨주소 */
                /* Type string | null */
                /* 예시) "https://stage.space.sauceflex.com/?returnUrl=${broadcastUrl}"*/
                "pc": null
           }
      }
}
1. 적용안(참고용)
{           
        "enter":{
            "webview":["sauceflexapp://showHeader?show=N","sauceflexapp://showActionBar?showYn=N"]
        },
        "share":{
            "use":true,
            "webview":null,
            "sns":true,
            "kakaoAppLink": null
        },
        "coupon": {
            "use":false
        },
        "guestLogin": {
            "use": false,
            "agreementUrl": null
        },
        "redirection": {
            "login": {
                "webview":null,
                "history": "href",
                "mobile": "https://sauceflex.com/example/sauceAuth?ret=${broadcastUrl}",
                "pc":  "https://sauceflex.com/example/sauceAuth?ret=${broadcastUrl}"
            },
             "broadcastClose": {
               "webview":"sauceflexapp://webPageClose",
               "history": "href",
               "mobile": null,
               "pc": "http://www.sauceflex.com/main"
           }
       }
}

📘

https://{ENV}player.sauceflex.com/broadcast/{방송 주소}?returnUrl=https://{이동할 주소}

ex)

https://{ENV}player.sauceflex.com/broadcast/lkmobidoo-964592b8d5e04507b9a8f4fe96ba89ca?returnUrl=https://www.saucelive.net/intro/

returnUrl = encodeURIComponent(https://www.saucelive.net/intro/)

http 또는 https 형태로 작성하시기 바랍니다.

ENV - "stage."(STAGE)

  ""(prod) 운영은 생략

자사몰 로그인 페이지

  • 로그인 페이지 URL과 소스라이브 페이지로 복귀할 방법 가이드 (returnUrl 등의 query string을 이용한 방법)
  • 로그인 이후, 서버와의 연동을 통하여 생성한 accessToken를 다음과 같이 returnUrl등을 통해 전달 받은 주소에 query string으로 붙여서 페이지 이동

📘

https://player.sauceflex.com/broadcast/{방송주소}?accessToken={생성된accessToken}

WebView에서 플레이어 연동 시 참고 사항

  • iOS X 이상의 기기에서 플레이어 화면 잘 현상을 방지하기 위해 SafeArea 영역 설정을 필히 진행해주시기 바랍니다.
  • Android Webview에서 재생 아이콘 표시 없이 영상이 재생되는 것을 원하실 경우에는 아래 코드를 활용해주시기 바랍니다. (해당 가이드는 파트너사 AOS앱 개발팀에서 진행)
    • override fun getDefaultVideoPoster(): Bitmap? { return Bitmap.createBitmap(10,10, Bitmap.Config.ARGB_8888) }

2-2. 연동 방법 (Iframe embeded)

기능 사용 여부

⭐️ stage, prod 환경 설정 - 궁금한 내용은 카카오톡, 채널톡 또는 담당자 이메일 [email protected]로 문의

{
      /* 쿠폰기능 관련 */       
      "coupon": {
          /* 쿠폰기능 사용여부 */
          /* Type boolean defaultValue true */
         "use":true       
      },      
      /* 비회원 관련 */
      "guestLogin":{
            /* 비회원 로그인 사용여부 (회원 or 비회원 택1)*/
            /* Type boolean defaultValue false*/
            "use":false,
           
            /* 비회원 로그인 개인정보 수집 약관 주소 */
            /* Type string|null defaultValue null*/
            "agreementUrl":null
      }
}

STEP 1. 방송 페이지를 을 이용하여 페이지에 추가 합니다.
<!-- 방송 주소 -->
<iframe src="<https://player.sauceflex.com/broadcast/{방송주소}?accessToken={accessToken}&gt;"&gt;</iframe>
<!-- 외부 유입 코드를 사용하려면 iframe을 그리기 전 요청받은 파라미터를 전달해줘야 합니다. 부모페이지에 호출된 queryString key중  fc 의 값을 전달해주셔야합니다. -->
<!-- example -->
<iframe src="<https://player.sauceflex.com/broadcast/{방송주소}?accessToken={accessToken}&gt;&amp;fc=value"&gt;</iframe>

STEP 2. 자바스크립트 window 객체에 'message' 이벤트를 수신하고 각 이벤트에 대해서 적절히 처리합니다.

window.addEventListener(
    "message",
    function(e) {
        // 이곳에 처리
        console.log(e.data);
    }, false
);

STEP 3. 메시지는 이벤트의 'data' 를 통해 JSON Type으로 전달됩니다. 각 이벤트는 아래와 같습니다.

  • 방송 입장 - 페이지 진입시 자동으로 호출
    • // event.data
      {
          key: 'sauceflexEnter',
          params: null
      }
      
  • 방송 종료
    • // event.data
      {
          key: 'sauceflexMoveExit',
          params: null
      }
      
  • 로그인 시도
    • // event.data
      {
          key: 'sauceflexMoveLogin',
          params: null
      }
      
  • 상품 클릭
    • {
          key: 'sauceflexMoveProduct',
          params: {
              linkUrl: String | null, // 상품 상세 정보의 url
              broadcastIdx: String    // 방송 번호
          }
      }
      
  • 공유하기
    • {
          key: 'sauceflexOnShare',
          params: {
              linkUrl: String // 공유 된 주소
          }
      }
      
  • 배너 클릭
    • {
          key: 'sauceflexMoveBanner',
          params: {
              bannerId: String // 배너 고유 아이디
              linkUrl: String // 배너에 등록된 url
              broadcastIdx: String // 방송 번호
          }
      }
      

2-3. 연동방법 (Webview)

Bridge & Message

아래와 같은 Bridge로 메시지가 전달됩니다. 각 메시지는 JSON 객체가 stringify 되어 전달됩니다.

  • sauceflexEnter(Void) - 페이지 진입 시 자동으로 호출

    • // 파라미터 없음
      
  • sauceflexMoveExit(Void)

    • // 파라미터 없음
      
  • sauceflexMoveLogin(Void)

    • // 파라미터 없음
      
  • sauceflexMoveProduct(message: String)

    • // Stringified JSON
      {
          linkUrl: String | null, // 상품 상세 정보의 url
          broadcastIdx: String    // 방송 번호
      }
      
  • sauceflexOnShare(message: String)

    • // Stringified JSON
      {
          linkUrl: String // 공유 된 주소
      }
      

Android

Android의 경우 "sauceflex" 이름을 가진 Bridge 중 해당 Bridge가 있는 경우 메시지를 전달하게 되며, 기본 동작은 취소됩니다.

import android.os.Handler
import android.webkit.JavascriptInterface
import android.widget.Toast
 
class AndroidBridge(private val activity: MainActivity) {
    private val handler = Handler()
 
    @JavascriptInterface
    fun sauceflexEnter() {
        handler.post {
            Toast.makeText(activity, "sauceflexEnter", Toast.LENGTH_SHORT).show()
        }
    }
 
    @JavascriptInterface
    fun sauceflexMoveExit() {
        handler.post {
            Toast.makeText(activity, "sauceflexMoveExit", Toast.LENGTH_SHORT).show()
        }
    }
  
   @JavascriptInterface
    fun sauceflexMoveLogin() {
        handler.post {
            Toast.makeText(activity, "sauceflexMoveLogin", Toast.LENGTH_SHORT).show()
        }
    }
 
    @JavascriptInterface
    fun sauceflexMoveProduct(message: String) {
        handler.post {
            Toast.makeText(activity, "sauceflexMoveProduct \\n $message", Toast.LENGTH_SHORT).show()
        }
    }
 
    @JavascriptInterface
    fun sauceflexOnShare(message: String) {
        handler.post {
            Toast.makeText(activity, "sauceflexOnShare \\n $message", Toast.LENGTH_SHORT).show()
        }
    }
  
   @JavascriptInterface
   fun sauceflexPictureInPicture () {
       handler.post {
           Toast.makeText(activity, "sauceflexPictureInPicture \\n $message", Toast.LENNGTH_SHORT).show()
       }
    }
 
    @JavascriptInterface
   fun sauceflexPictureInPictureNoEvent () {
       handler.post {
           Toast.makeText(activity, "sauceflexPictureInPictureNoEvent \\n $message", Toast.LENNGTH_SHORT).show()
       }
    }
 
}
  

iOS

extension ViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController,
                                    didReceive message: WKScriptMessage) {
        switch (message.name) {
            case "sauceflexEnter":
                print("sauceflexEnter")
                break
 
            case "sauceflexMoveExit":
                print("sauceflexMoveExit")
                break
 
            case "sauceflexMoveLogin":
                print("sauceflexMoveLogin")
                break
 
            case "sauceflexMoveProduct":
                print("sauceflexMoveProduct")
                print(message.body)
                break
 
            case "sauceflexOnShare":
                print("sauceflexOnShare")
                print(message.body)
                break
            
             case "sauceflexPictureInPicture":
                print("sauceflexPictureInPicture")
                print(message.body)
                break
 
             case "sauceflexPictureInPictureNoEvent":
                print("sauceflexPictureInPictureNoEvent")
                print(message.body)
                break
 
            default:
                print("message.name \\(message.name) not handled.")
        }
    }
}