AvSessionController.ets 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * Copyright (c) 2024 Huawei Device Co., Ltd.
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import { hilog } from '@kit.PerformanceAnalysisKit';
  16. import { common, wantAgent } from '@kit.AbilityKit';
  17. import { BusinessError } from '@kit.BasicServicesKit';
  18. import { avSession } from '@kit.AVSessionKit';
  19. import { BackgroundTaskManager } from '../common/util/BackgroundTaskManager';
  20. import { VideoItem } from '../viewmodel/VideoItem';
  21. import { ImageUtil, PreferencesUtil } from '@pura/harmony-utils';
  22. import { SettingPage } from '../pages/SettingPage';
  23. import LyricUtil from '../common/util/LyricUtil';
  24. import ImageUtils from '../common/util/ImageUtils';
  25. const TAG = 'onecold AvSessionController';
  26. export class AvSessionController {
  27. private static instance: AvSessionController | null;
  28. private context: common.UIAbilityContext | undefined = undefined;
  29. private avSession: avSession.AVSession | undefined = undefined;
  30. private avSessionMetadata: avSession.AVMetadata | undefined = undefined;
  31. constructor(isVideo:boolean) {
  32. this.initAvSession(isVideo);
  33. }
  34. public static getInstance(isVideo:boolean): AvSessionController {
  35. if (!AvSessionController.instance) {
  36. AvSessionController.instance = new AvSessionController(isVideo);
  37. }
  38. return AvSessionController.instance;
  39. }
  40. public initAvSession(isVideo:boolean) {
  41. if(isVideo){
  42. let isBgPlayOpen = PreferencesUtil.getBooleanSync(SettingPage.IS_BGPLAY_OPEN,true)
  43. if(!isBgPlayOpen)
  44. return
  45. }
  46. this.context = AppStorage.get('context');
  47. if (!this.context) {
  48. hilog.info(0x0000, TAG, `session create failed : conext is undefined`);
  49. return;
  50. }
  51. let type: avSession.AVSessionType = isVideo ? 'video' : 'audio';
  52. avSession.createAVSession(this.context, 'sessionName', type).then(async (avSession) => {
  53. this.avSession = avSession;
  54. hilog.info(0x0000, TAG, `session create successed : sessionId : ${this.avSession.sessionId}`);
  55. BackgroundTaskManager.startContinuousTask(this.context);
  56. this.setLaunchAbility();
  57. this.avSession.activate();
  58. this.avSession.setExtras({
  59. requireAbilityList: ['url-cast']
  60. });
  61. }).catch((error:Error) => {
  62. console.error('Failed to create AVSession:', error);
  63. });
  64. }
  65. private setLaunchAbility() {
  66. if (!this.context) {
  67. return;
  68. }
  69. const wantAgentInfo: wantAgent.WantAgentInfo = {
  70. wants: [
  71. {
  72. bundleName: this.context.abilityInfo.bundleName,
  73. abilityName: this.context.abilityInfo.name
  74. }
  75. ],
  76. operationType: wantAgent.OperationType.START_ABILITIES,
  77. requestCode: 0,
  78. wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
  79. };
  80. wantAgent.getWantAgent(wantAgentInfo).then((agent) => {
  81. if (this.avSession) {
  82. this.avSession.setLaunchAbility(agent);
  83. }
  84. });
  85. }
  86. public getAvSession() {
  87. return this.avSession;
  88. }
  89. public getAvSessionMetadata() {
  90. return this.avSessionMetadata;
  91. }
  92. public async setAVMetadata(curSource: VideoItem, duration: number) {
  93. if (curSource === undefined) {
  94. hilog.error(0x0000, TAG, 'SetAVMetadata Error, curSource is null');
  95. return;
  96. }
  97. BackgroundTaskManager.startContinuousTask(this.context);
  98. const imagePixMap = await ImageUtil.getPixelMapFromMedia($r('app.media.ic_avatar7'));
  99. let metadata: avSession.AVMetadata = {
  100. assetId: `${curSource.filePath}`,
  101. title: curSource.name,
  102. filter: avSession.ProtocolType.TYPE_CAST_PLUS_STREAM|avSession.ProtocolType.TYPE_DLNA,
  103. mediaImage: imagePixMap,
  104. duration: duration,
  105. // 如果是DRM资源,配置支持的DRM uuid 用于设备过滤。非DRM资源不配置。
  106. // drmSchemes: ['3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c']
  107. };
  108. if (this.avSession) {
  109. this.avSession.setAVMetadata(metadata).then(() => {
  110. this.avSessionMetadata = metadata;
  111. hilog.info(0x0000, TAG, 'SetAVMetadata successfully');
  112. }).catch((err: BusinessError) => {
  113. hilog.error(0x0000, TAG, `SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`);
  114. });
  115. }
  116. }
  117. public async setAVMetadataMusic(curSource: VideoItem, duration: number,lyricContent?:string) {
  118. if (curSource === undefined) {
  119. hilog.error(0x0000, TAG, 'SetAVMetadata Error, curSource is null');
  120. return;
  121. }
  122. try {
  123. BackgroundTaskManager.startContinuousTask(this.context);
  124. let pixelMapPath:string|undefined = curSource.pixelMapPath
  125. let imagePixMap: PixelMap|string ;
  126. if(pixelMapPath){
  127. imagePixMap = await ImageUtils.imagePathToPixelMap(pixelMapPath)
  128. }else{
  129. imagePixMap = await ImageUtil.getPixelMapFromMedia($r('app.media.ic_avatar2'));
  130. }
  131. let lyric = ''
  132. if(lyricContent)
  133. lyric = LyricUtil.convertLyricToSimpleLrc(lyricContent)
  134. hilog.info(0x0000, TAG, 'onecold SetAVMetadata successfully curSource.pixelMapPath '+curSource.pixelMapPath);
  135. let metadata: avSession.AVMetadata = {
  136. assetId: `${curSource.filePath}`,
  137. title: curSource.name,
  138. subtitle: curSource.album,
  139. // 发现Cast+ Stream 和 DLNA协议设备,TYPE_CAST_PLUS_STREAM为默认必选
  140. filter: avSession.ProtocolType.TYPE_CAST_PLUS_STREAM|avSession.ProtocolType.TYPE_DLNA,
  141. artist: curSource.artist,
  142. mediaImage: imagePixMap,
  143. duration: duration,
  144. lyric:lyric,
  145. // 如果是DRM资源,配置支持的DRM uuid 用于设备过滤。非DRM资源不配置。
  146. // drmSchemes: ['3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c']
  147. };
  148. if (this.avSession) {
  149. this.avSession.setAVMetadata(metadata).then(() => {
  150. this.avSessionMetadata = metadata;
  151. hilog.info(0x0000, TAG, 'SetAVMetadata successfully');
  152. }).catch((err: BusinessError) => {
  153. hilog.error(0x0000, TAG, `SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`);
  154. });
  155. }
  156. } catch (error) {
  157. console.warn(' setAVMetadataMusic:', error.message);
  158. }
  159. }
  160. public setAvSessionPlayState(playbackState: avSession.AVPlaybackState) {
  161. if (this.avSession) {
  162. BackgroundTaskManager.startContinuousTask(this.context);
  163. this.avSession.setAVPlaybackState(playbackState, (err: BusinessError) => {
  164. if (err) {
  165. hilog.error(0x0000, TAG, `SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`);
  166. } else {
  167. hilog.info(0x0000, TAG, 'SetAVPlaybackState successfully');
  168. }
  169. });
  170. }
  171. }
  172. async unregisterSessionListener() {
  173. if (!this.avSession) {
  174. return;
  175. }
  176. this.avSession.off('play');
  177. this.avSession.off('pause');
  178. this.avSession.off('playNext');
  179. this.avSession.off('playPrevious');
  180. this.avSession.off('setLoopMode');
  181. this.avSession.off('seek');
  182. this.avSession.off('toggleFavorite');
  183. this.avSession.destroy()
  184. BackgroundTaskManager.stopContinuousTask(this.context);
  185. }
  186. }