1"use strict";(globalThis.webpackChunkbambuser_docs||=[]).push([[2873],{1746(e,n,r){r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>l});const d=JSON.parse('{"id":"mobileSDK/android/sv-android-delegate-protocol","title":"Delegate Protocol","description":"BambuserVideoPlayerDelegate interface: onNewEventReceived, onErrorOccurred, onVideoStatusChanged, onVideoProgress, ViewActions, PlayerActions, and BambuserVideoState.","source":"@site/shoppable-video/mobileSDK/android/delegate-protocol.mdx","sourceDirName":"mobileSDK/android","slug":"/mobileSDK/android/mobile-sdk/android/delegate-protocol","permalink":"/docs/shoppable-video/mobileSDK/android/mobile-sdk/android/delegate-protocol","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"id":"sv-android-delegate-protocol","title":"Delegate Protocol","description":"BambuserVideoPlayerDelegate interface: onNewEventReceived, onErrorOccurred, onVideoStatusChanged, onVideoProgress, ViewActions, PlayerActions, and BambuserVideoState.","sidebar_label":"Delegate Protocol","slug":"mobile-sdk/android/delegate-protocol"},"sidebar":"someSidebars","previous":{"title":"Setup","permalink":"/docs/shoppable-video/mobileSDK/android/mobile-sdk/android/setup"},"next":{"title":"Configuration and Functions","permalink":"/docs/shoppable-video/mobileSDK/android/mobile-sdk/android/configuration-and-functions"}}');var i=r(74848),t=r(28453);const s={id:"sv-android-delegate-protocol",title:"Delegate Protocol",description:"BambuserVideoPlayerDelegate interface: onNewEventReceived, onErrorOccurred, onVideoStatusChanged, onVideoProgress, ViewActions, PlayerActions, and BambuserVideoState.",sidebar_label:"Delegate Protocol",slug:"mobile-sdk/android/delegate-protocol"},o="Delegate Protocol",c={},l=[{value:"Interface Definition",id:"interface-definition",level:2},{value:"Method Reference",id:"method-reference",level:2},{value:"<code>onNewEventReceived</code>",id:"onneweventreceived",level:3},{value:"<code>onErrorOccurred</code>",id:"onerroroccurred",level:3},{value:"<code>onVideoStatusChanged</code>",id:"onvideostatuschanged",level:3},{value:"<code>onVideoProgress</code>",id:"onvideoprogress",level:3},{value:"BambuserVideoState",id:"bambuservideostate",level:2},{value:"ViewActions",id:"viewactions",level:2},{value:"PlayerActions",id:"playeractions",level:2},{value:"Full Implementation Example",id:"full-implementation-example",level:2},{value:"Next Steps",id:"next-steps",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"delegate-protocol",children:"Delegate Protocol"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"BambuserVideoPlayerDelegate"})," is the interface through which the SDK communicates back to your app. Implement it to respond to player events, errors, state changes, and playback progress."]}),"\n",(0,i.jsx)(n.h2,{id:"interface-definition",children:"Interface Definition"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-kotlin",metastring:'title="BambuserVideoPlayerDelegate.kt"',children:"interface BambuserVideoPlayerDelegate {\n // Required\n fun onNewEventReceived(playerId: String, event: BambuserEventPayload, viewAction: ViewActions)\n fun onErrorOccurred(playerId: String, error: Exception)\n\n // Optional\n fun onVideoStatusChanged(playerId: String, state: BambuserVideoState, playerActions: PlayerActions) {}\n fun onVideoProgress(playerId: String, duration: Long, currentTime: Long) {}\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"onVideoStatusChanged"})," and ",(0,i.jsx)(n.code,{children:"onVideoProgress"})," have default no-op implementations so you only need to override the methods you use."]}),"\n",(0,i.jsx)(n.h2,{id:"method-reference",children:"Method Reference"}),"\n",(0,i.jsx)(n.h3,{id:"onneweventreceived",children:(0,i.jsx)(n.code,{children:"onNewEventReceived"})}),"\n",(0,i.jsx)(n.p,{children:"Called whenever the player emits a named event. This is the primary integration point for cart operations, product hydration, and screen-mode transitions."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Parameter"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"playerId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"String"})}),(0,i.jsx)(n.td,{children:"Unique ID of the player instance that emitted the event"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"event"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BambuserEventPayload"})}),(0,i.jsxs)(n.td,{children:["The event payload; use ",(0,i.jsx)(n.code,{children:"event.event"})," for the event name and ",(0,i.jsx)(n.code,{children:"event.data"})," for the payload"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"viewAction"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"ViewActions"})}),(0,i.jsx)(n.td,{children:"Handle to trigger UI transitions on this player"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"onerroroccurred",children:(0,i.jsx)(n.code,{children:"onErrorOccurred"})}),"\n",(0,i.jsx)(n.p,{children:"Called when the player encounters an unrecoverable error. Log the error or show a fallback UI."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Parameter"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"playerId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"String"})}),(0,i.jsx)(n.td,{children:"ID of the player that errored"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"error"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Exception"})}),(0,i.jsx)(n.td,{children:"The exception describing what went wrong"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"onvideostatuschanged",children:(0,i.jsx)(n.code,{children:"onVideoStatusChanged"})}
1),"\n",(0,i.jsxs)(n.p,{children:["Called when the player's playback state changes. Use ",(0,i.jsx)(n.code,{children:"playerActions"})," to programmatically control playback."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Parameter"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"playerId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"String"})}),(0,i.jsx)(n.td,{children:"ID of the player whose state changed"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"state"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BambuserVideoState"})}),(0,i.jsx)(n.td,{children:"The new state (see table below)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"playerActions"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"PlayerActions"})}),(0,i.jsxs)(n.td,{children:["Handle to call ",(0,i.jsx)(n.code,{children:"play()"}),", ",(0,i.jsx)(n.code,{children:"pause()"}),", ",(0,i.jsx)(n.code,{children:"mute()"}),", ",(0,i.jsx)(n.code,{children:"unMute()"}),", or ",(0,i.jsx)(n.code,{children:"seek(to: Long)"})]})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"onvideoprogress",children:(0,i.jsx)(n.code,{children:"onVideoProgress"})}),"\n",(0,i.jsx)(n.p,{children:"Called periodically during playback with the current time position."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Parameter"}),(0,i.jsx)(n.th,{children:"Type"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"playerId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"String"})}),(0,i.jsx)(n.td,{children:"ID of the playing video"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"duration"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Long"})}),(0,i.jsxs)(n.td,{children:["Total duration in ",(0,i.jsx)(n.strong,{children:"seconds"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"currentTime"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Long"})}),(0,i.jsxs)(n.td,{children:["Current playback position in ",(0,i.jsx)(n.strong,{children:"seconds"})]})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"bambuservideostate",children:"BambuserVideoState"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"State"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"INITIALIZED"})}),(0,i.jsx)(n.td,{children:"Player instance has been created"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"CONSTRUCTION"})}),(0,i.jsx)(n.td,{children:"Player is constructing its internal components"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"LOADING"})}),(0,i.jsx)(n.td,{children:"Player is loading media"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BUFFERING"})}),(0,i.jsx)(n.td,{children:"Video is buffering during playback"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"READY"})}),(0,i.jsx)(n.td,{children:"Player is ready to begin playback"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"PLAYING"})}),(0,i.jsx)(n.td,{children:"Video is actively playing"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"PAUSED"})}),(0,i.jsx)(n.td,{children:"Playback is paused"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"ERROR"})}),(0,i.jsxs)(n.td,{children:["An error occurred; see ",(0,i.jsx)(n.code,{children:"onErrorOccurred"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"COMPLETED"})}),(0,i.jsx)(n.td,{children:"Video reached the end"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"CLOSED"})}),(0,i.jsx)(n.td,{children:"User dismissed the player"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"viewactions",children:"ViewActions"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"ViewActions"})," controls the screen mode of an individual player instance. Call it from ",(0,i.jsx)(n.code,{children:"onNewEventReceived"}),"."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Method"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"switchScreenMo
1de(ScreenMode.FullScreenMode)"})}),(0,i.jsx)(n.td,{children:"Expand the player to fullscreen"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"switchScreenMode(ScreenMode.PreviewMode)"})}),(0,i.jsx)(n.td,{children:"Collapse back to the in-line preview strip"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"invoke(function: String, arguments: Any?)"})}),(0,i.jsxs)(n.td,{children:["Invoke a named function on the player view (e.g. ",(0,i.jsx)(n.code,{children:'"updateProductWithData"'}),")"]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"notifyView(callbackKey: String, info: Map<String, Any?>)"})}),(0,i.jsx)(n.td,{children:"Send a callback response back to the player (e.g. to confirm a cart action)"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"playeractions",children:"PlayerActions"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"PlayerActions"})," is received in ",(0,i.jsx)(n.code,{children:"onVideoStatusChanged"})," and controls playback programmatically."]}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Method"}),(0,i.jsx)(n.th,{children:"Description"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"play()"})}),(0,i.jsx)(n.td,{children:"Start or resume playback"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"pause()"})}),(0,i.jsx)(n.td,{children:"Pause playback"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"mute()"})}),(0,i.jsx)(n.td,{children:"Mute the player audio"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"unMute()"})}),(0,i.jsx)(n.td,{children:"Unmute the player audio"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"seek(to: Long)"})}),(0,i.jsxs)(n.td,{children:["Seek to a position in ",(0,i.jsx)(n.strong,{children:"seconds"})]})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"full-implementation-example",children:"Full Implementation Example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-kotlin",metastring:'title="MyVideoDelegate.kt"',children:'val delegate = object : BambuserVideoPlayerDelegate {\n\n override fun onNewEventReceived(\n playerId: String,\n event: BambuserEventPayload,\n viewAction: ViewActions,\n ) {\n when (event.event) {\n // Expand to fullscreen when the user taps the preview\n "preview-should-expand" -> {\n viewAction.switchScreenMode(ScreenMode.FullScreenMode)\n }\n // Collapse back to preview when the user closes the player\n "close" -> {\n viewAction.switchScreenMode(ScreenMode.PreviewMode)\n }\n // Handle cart and product events \u2014 see sibling pages\n "should-add-item-to-cart" -> { /* \u2192 see Cart Integration */ }\n "provide-product-data" -> { /* \u2192 see Product Hydration */ }\n }\n }\n\n override fun onErrorOccurred(playerId: String, error: Exception) {\n Log.e("Bambuser", "Player [$playerId] error: ${error.message}", error)\n // Show a fallback UI or retry\n }\n\n override fun onVideoStatusChanged(\n playerId: String,\n state: BambuserVideoState,\n playerActions: PlayerActions,\n ) {\n when (state) {\n BambuserVideoState.PLAYING -> Log.d("Bambuser", "[$playerId] now playing")\n BambuserVideoState.PAUSED -> Log.d("Bambuser", "[$playerId] paused")\n BambuserVideoState.COMPLETED -> Log.d("Bambuser", "[$playerId] finished")\n BambuserVideoState.ERROR -> Log.e("Bambuser", "[$playerId] entered error state")\n else -> Unit\n }\n }\n\n override fun onVideoProgress(playerId: String, duration: Long, currentTime: Long) {\n val percent = if (duration > 0) (currentTime * 100 / duration) else 0\n Log.v("Bambuser", "[$playerId] $percent% ($currentTime s / $duration s)")\n }\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"playerId"})," parameter lets you distinguish between multiple simultaneous player instances \u2014 useful when rendering a carousel where several players can be in preview mode at once."]})}),"\n",(0,i.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"/docs/shoppable-video/mobileSDK/android/mobile-sdk/android/cart-integration",children:"Cart integration"})," \u2014 handle ",(0,i.jsx)(n.code,{children:"should-add-item-to-cart"})," in ",(0,i.jsx)(n.code,{children:"onNewEventReceived"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"/docs/shoppable-video/mobileSDK/android/mobile-sdk/android/product-hydration",children:"Product hydration"})," \u2014 handle ",(0,i.jsx)(n.code,{children:"provide-product-data"})," to enrich player products."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453(e,n,r){r.d(n,{R:()=>s,x:()=>o});var d=r(96540);const i={},t=d.createContext(i);function s(e){const n=d.useContext(t);return d.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),d.createElement(t.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.