1"use strict";(self.webpackChunkdocusaurus=self.webpackChunkdocusaurus||[]).push([[6154],{11470:(e,n,a)=>{a.d(n,{A:()=>w});var i=a(96540),t=a(34164),r=a(23104),o=a(56347),s=a(205),l=a(57485),d=a(31682),c=a(89466);function u(e){return i.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function p(e){const{values:n,children:a}=e;return(0,i.useMemo)(()=>{const e=n??function(e){return u(e).map(({props:{value:e,label:n,attributes:a,default:i}})=>({value:e,label:n,attributes:a,default:i}))}(a);return function(e){const n=(0,d.X)(e,(e,n)=>e.value===n.value);if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e},[n,a])}function h({value:e,tabValues:n}){return n.some(n=>n.value===e)}function m({queryString:e=!1,groupId:n}){const a=(0,o.W6)(),t=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,l.aZ)(t),(0,i.useCallback)(e=>{if(!t)return;const n=new URLSearchParams(a.location.search);n.set(t,e),a.replace({...a.location,search:n.toString()})},[t,a])]}function b(e){const{defaultValue:n,queryString:a=!1,groupId:t}=e,r=p(e),[o,l]=(0,i.useState)(()=>function({defaultValue:e,tabValues:n}){if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!h({value:e,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const a=n.find(e=>e.default)??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:r})),[d,u]=m({queryString:a,groupId:t}),[b,f]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[a,t]=(0,c.Dv)(n);return[a,(0,i.useCallback)(e=>{n&&t.set(e)},[n,t])]}({groupId:t}),g=(()=>{const e=d??b;return h({value:e,tabValues:r})?e:null})();(0,s.A)(()=>{g&&l(g)},[g]);return{selectedValue:o,selectValue:(0,i.useCallback)(e=>{if(!h({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),f(e)},[u,f,r]),tabValues:r}}var f=a(92303);const g={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var y=a(74848);function k({className:e,block:n,selectedValue:a,selectValue:i,tabValues:o}){const s=[],{blockElementScrollPositionUntilNextRender:l}=(0,r.a_)(),d=e=>{const n=e.currentTarget,t=s.indexOf(n),r=o[t].value;r!==a&&(l(n),i(r))},c=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const a=s.indexOf(e.currentTarget)+1;n=s[a]??s[0];break}case"ArrowLeft":{const a=s.indexOf(e.currentTarget)-1;n=s[a]??s[s.length-1];break}}n?.focus()};return(0,y.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":n},e),children:o.map(({value:e,label:n,attributes:i})=>(0,y.jsx)("li",{role:"tab",tabIndex:a===e?0:-1,"aria-selected":a===e,ref:e=>s.push(e),onKeyDown:c,onClick:d,...i,className:(0,t.A)("tabs__item",g.tabItem,i?.className,{"tabs__item--active":a===e}),children:n??e},e))})}function v({lazy:e,children:n,selectedValue:a}){const t=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){const e=t.find(e=>e.props.value===a);return e?(0,i.cloneElement)(e,{className:"margin-top--md"}):null}return(0,y.jsx)("div",{className:"margin-top--md",children:t.map((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==a}))})}function x(e){const n=b(e);return(0,y.jsxs)("div",{className:(0,t.A)("tabs-container",g.tabList),
1children:[(0,y.jsx)(k,{...n,...e}),(0,y.jsx)(v,{...n,...e})]})}function w(e){const n=(0,f.A)();return(0,y.jsx)(x,{...e,children:u(e.children)},String(n))}},19365:(e,n,a)=>{a.d(n,{A:()=>o});a(96540);var i=a(34164);const t={tabItem:"tabItem_Ymn6"};var r=a(74848);function o({children:e,hidden:n,className:a}){return(0,r.jsx)("div",{role:"tabpanel",className:(0,i.A)(t.tabItem,a),hidden:n,children:e})}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>s});var i=a(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}},70081:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>d,toc:()=>u});var i=a(74848),t=a(28453),r=a(11470),o=a(19365);const s={id:"background-playback",title:"Running Videos in Background with VdoCipher in React Native",sidebar_label:"Background Playback"},l=void 0,d={id:"mobile/react-native/background-playback",title:"Running Videos in Background with VdoCipher in React Native",description:"Background playback allows media to continue playing seamlessly while multitasking or switching apps. This feature ensures that music, podcasts, or videos remain uninterrupted, even when the screen is locked or the app is exited. Starting with version 1.21.0, vdocipher-rn-bridge package offers smooth support for background playback, enabling uninterrupted media enjoyment across various device activities.",source:"@site/docs/mobile/react-native/background-playback.md",sourceDirName:"mobile/react-native",slug:"/mobile/react-native/background-playback",permalink:"/docs/mobile/react-native/background-playback",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{id:"background-playback",title:"Running Videos in Background with VdoCipher in React Native",sidebar_label:"Background Playback"},sidebar:"mobile",previous:{title:"Offline downloads",permalink:"/docs/mobile/react-native/offline"},next:{title:"Picture in Picture",permalink:"/docs/mobile/react-native/pip-mode"}},c={},u=[{value:"Configuring Background Playback in Android",id:"configuring-background-playback-in-android",level:2},{value:"Playback Modes",id:"playback-modes",level:3},{value:"How to Implement?",id:"how-to-implement",level:3},{value:"1. Add Permission for Media Playback Service",id:"1-add-permission-for-media-playback-service",level:4}
1,{value:"2. Configure Background Playback",id:"2-configure-background-playback",level:4},{value:"Configuring Background Playback in iOS",id:"configuring-background-playback-in-ios",level:2},{value:"Playback Modes",id:"playback-modes-1",level:3},{value:"How to Implement?",id:"how-to-implement-1",level:3}];function p(e){const n={admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(n.p,{children:["Background playback allows media to continue playing seamlessly while multitasking or switching apps. This feature ensures that music, podcasts, or videos remain uninterrupted, even when the screen is locked or the app is exited. Starting with version 1.21.0, ",(0,i.jsx)(n.strong,{children:"vdocipher-rn-bridge"})," package offers smooth support for background playback, enabling uninterrupted media enjoyment across various device activities."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-background-playback-in-android",children:"Configuring Background Playback in Android"}),"\n",(0,i.jsx)(n.h3,{id:"playback-modes",children:"Playback Modes"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"vdocipher-rn-bridge"})," package offers three playback modes for Android, each providing a different level of persistence:"]}),"\n",(0,i.jsxs)(r.A,{children:[(0,i.jsxs)(o.A,{value:"default",label:"Default",default:!0,children:[(0,i.jsx)(n.p,{children:"The media will immediately pause when the user closes or navigates away from the player screen."}),(0,i.jsx)(n.p,{children:"Ideal for applications like e-learning platforms, where it's important for users to stay focused on the content without switching between apps."}),(0,i.jsx)("video",{src:"https://www.vdocipher.com/files/docs-videos/vdo_android_bg_default_demo.mp4",muted:"muted",loop:"loop",autoplay:"autoplay",controls:!0,style:{maxWidth:"min(100%, 450px)",border:"1px solid #dddddd"}})]}),(0,i.jsxs)(o.A,{value:"continue_playback_on_back_press",label:"Continue playback on back press",children:[(0,i.jsx)(n.p,{children:"Playback pauses when the app is completely exited, but continues if the app is minimized or the back button is pressed."}),(0,i.jsx)(n.p,{children:"Ideal for apps where users might briefly switch tasks, like news or streaming apps. \ud83d\udcf0"}),(0,i.jsx)("video",{src:"https://www.vdocipher.com/files/docs-videos/vdo_android_bg_continue_on_back_press_demo.mp4",muted:"muted",loop:"loop",autoplay:"autoplay",controls:!0,style:{maxWidth:"min(100%, 450px)",border:"1px solid #dddddd"}})]}),(0,i.jsxs)(o.A,{value:"continue_playback_on_app_exit",label:"Continue playback on app exit",children:[(0,i.jsx)(n.p,{children:"The media continues playing in the background, regardless of whether the app is minimized or fully exited."}),(0,i.jsx)(n.p,{children:"Perfect for music and podcast apps where continuous playback is a core feature, offering an uninterrupted experience. \ud83c\udfb5"}),(0,i.jsx)("video",{src:"https://www.vdocipher.com/files/docs-videos/vdo_android_bg_continue_on_app_exit_demo.mp4",muted:"muted",loop:"loop",autoplay:"autoplay",controls:!0,style:{maxWidth:"min(100%, 450px)",border:"1px solid #dddddd"}})]})]}),"\n",(0,i.jsx)(n.h3,{id:"how-to-implement",children:"How to Implement?"}),"\n",(0,i.jsx)(n.h4,{id:"1-add-permission-for-media-playback-service",children:"1. Add Permission for Media Playback Service"}),"\n",(0,i.jsxs)(n.p,{children:["To enable background playback in Android (for SDK version 34 or higher), add the following permission to your ",(0,i.jsx)(n.code,{children:"AndroidManifest.xml"})," file, located at ",(0,i.jsx)(n.code,{children:"android/app/src/main/AndroidManifest.xml"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-xml",children:'<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />\n\n <application\n ..>\n ..\n </application>\n</manifest>\n'})}),"\n",(0,i.jsx)(n.p,{children:"This permission is required for media playback to continue in the background."}),"\n",(0,i.jsx)(n.h4,{id:"2-configure-background-playback",children:"2. Configure Backgroun
1d Playback"}),"\n",(0,i.jsxs)(n.p,{children:["To set up background playback, configure the playback mode before your ",(0,i.jsx)(n.code,{children:"VdoPlayerView"})," component is added."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:'const {VdoPlayerSettings} = NativeModules;\n\nconst playerSettings: PlayerSettings = {vdoPlaybackModeAndroid: "continue_playback_on_app_exit"}\n\nuseEffect(() => {\n VdoPlayerSettings.applySettings(playerSettings);\n }, []);\n'})}),"\n",(0,i.jsxs)(n.admonition,{title:"Choose the mode that fits your app",type:"tip",children:[(0,i.jsxs)(n.p,{children:["Replace ",(0,i.jsx)(n.code,{children:"continue_playback_on_app_exit"})," in the snippet with the mode that best suits your app's needs:"]}),(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"default"}),": Stops playback when the player screen is closed."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"continue_playback_on_back_press"}),": Continues playback when the app is minimized but stops when fully closed."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"continue_playback_on_app_exit"}),": Keeps playback running even after the app is closed."]}),"\n"]}),(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.em,{children:["If playback behavior is not set, the player will default to ",(0,i.jsx)(n.strong,{children:"default"})," behavior."]})})]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-background-playback-in-ios",children:"Configuring Background Playback in iOS"}),"\n",(0,i.jsx)(n.h3,{id:"playback-modes-1",children:"Playback Modes"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.strong,{children:"vdocipher-rn-bridge"})," package offers single playback mode for iOS."]}),"\n",(0,i.jsxs)(r.A,{children:[(0,i.jsxs)(o.A,{value:"false",label:"Background Playback Disabled",default:!0,children:[(0,i.jsx)(n.p,{children:"The media will immediately pause when the user closes or navigates away from the player screen or presses home."}),(0,i.jsx)(n.p,{children:"Ideal for applications like e-learning platforms, where it's important for users to stay focused on the content without switching between apps."}),(0,i.jsx)("video",{src:"https://www.vdocipher.com/files/docs-videos/vdo_iOS_bg_enabled_demo.mp4",muted:"muted",loop:"loop",autoplay:"autoplay",controls:!0,style:{maxWidth:"min(100%, 450px)",border:"1px solid #dddddd"}})]}),(0,i.jsxs)(o.A,{value:"true",label:"Background Playback Enabled",children:[(0,i.jsx)(n.p,{children:"The media will not pause when navigating to home or other apps when the player instance is not discarded but will immediately pause when the user closes the player screen."}),(0,i.jsx)(n.p,{children:"Ideal for apps where users might briefly switch tasks, like news or streaming apps. \ud83d\udcf0"}),(0,i.jsx)("video",{src:"https://www.vdocipher.com/files/docs-videos/vdo_iOS_bg_disabled_demo.mp4",muted:"muted",loop:"loop",autoplay:"autoplay",controls:!0,style:{maxWidth:"min(100%, 450px)",border:"1px solid #dddddd"}})]})]}),"\n",(0,i.jsx)(n.h3,{id:"how-to-implement-1",children:"How to Implement?"}),"\n",(0,i.jsxs)(n.p,{children:["You can enable background mode in iOS by passing ",(0,i.jsx)(n.code,{children:"true"})," for ",(0,i.jsx)(n.code,{children:"vdoPlaybackModeiOS"})," when setting ",(0,i.jsx)(n.code,{children:"VdoPlayerSettings"}),". By default, background mode is desabled in iOS."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-js",children:"const {VdoPlayerSettings} = NativeModules;\n\nconst playerSettings: PlayerSettings = {vdoPlaybackModeiOS: true}\n\nuseEffect(() => {\n VdoPlayerSettings.applySettings(playerSettings);\n }, []);\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}}}]);
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.