1e41f4b71Sopenharmony_ci# Media Data Demuxing
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciYou can call the native APIs provided by the AVDemuxer module to demux media data. The demuxing involves extracting media samples such as audio, video, and subtitles from bit stream data, and obtaining information related to Digital Rights Management (DRM).
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciCurrently, two data input types are supported: remote connection (over HTTP) and File Descriptor (FD).
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciThe following demuxing formats are supported:
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci| Media Format | Muxing Format                     | Stream Format                     |
10e41f4b71Sopenharmony_ci| -------- | :----------------------------| :----------------------------|
11e41f4b71Sopenharmony_ci| Audio/Video    | mp4                        |<!--RP1-->Video stream: AVC (H.264); audio stream: AAC and MPEG (MP3); subtitle stream: WEBVTT<!--RP1End-->|
12e41f4b71Sopenharmony_ci| Audio/Video    | fmp4                       |<!--RP2-->Video stream: AVC (H.264); audio stream: AAC and MPEG (MP3)<!--RP2End-->|
13e41f4b71Sopenharmony_ci| Audio/Video    | mkv                        |<!--RP3-->Video stream: AVC (H.264); audio stream: AAC, MPEG (MP3), and OPUS<!--RP3End-->|
14e41f4b71Sopenharmony_ci| Audio/Video    | mpeg-ts                    |<!--RP4-->Video stream: AVC (H.264); audio stream: AAC and MPEG (MP3)<!--RP4End-->|
15e41f4b71Sopenharmony_ci| Audio/Video    | flv                        |<!--RP5-->Video stream: AVC (H.264); audio stream: AAC<!--RP5End-->|
16e41f4b71Sopenharmony_ci| Audio      | m4a                        |<!--RP6-->Audio stream: AAC<!--RP6End-->|
17e41f4b71Sopenharmony_ci| Audio      | aac                        |Audio stream: AAC|
18e41f4b71Sopenharmony_ci| Audio      | mp3                        |Audio stream: MPEG (MP3)|
19e41f4b71Sopenharmony_ci| Audio      | ogg                        |Audio stream: OGG|
20e41f4b71Sopenharmony_ci| Audio      | flac                       |Audio stream: FLAC|
21e41f4b71Sopenharmony_ci| Audio      | wav                        |Audio stream: PCM and PCM-MULAW|
22e41f4b71Sopenharmony_ci| Audio      | amr                        |Audio stream: AMR (AMR-NB and AMR-WB)|
23e41f4b71Sopenharmony_ci| Audio      | ape                        |Audio stream: APE|
24e41f4b71Sopenharmony_ci| External subtitle  | srt                        |Subtitle stream: SRT|
25e41f4b71Sopenharmony_ci| External subtitle  | webvtt                     |Subtitle stream: WEBVTT|
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ciThe DRM demuxing capability supports the following formats: <!--RP7-->mp4 (H.264 and AAC) and mpeg-ts (H.264 and AAC)<!--RP7End-->.
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci**Usage Scenario**
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci- Audio and video playback
32e41f4b71Sopenharmony_ci  
33e41f4b71Sopenharmony_ci  Demux media streams, decode the samples obtained through demuxing, and play the samples.
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci- Audio and video editing
36e41f4b71Sopenharmony_ci  
37e41f4b71Sopenharmony_ci  Demux media streams, and edit the specified samples.
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ci- Media file format conversion
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ci  Demux media streams, and encapsulate them into a new file format.
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci## How to Develop
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ciRead [AVDemuxer](../../reference/apis-avcodec-kit/_a_v_demuxer.md) and [AVSource](../../reference/apis-avcodec-kit/_a_v_source.md) for the API reference.
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci> **NOTE**
48e41f4b71Sopenharmony_ci>
49e41f4b71Sopenharmony_ci> - To call the demuxer APIs to parse a network playback path, declare the **ohos.permission.INTERNET** permission by following the instructions provided in [Declaring Permissions](../../security/AccessToken/declare-permissions.md).
50e41f4b71Sopenharmony_ci> - To call the demuxer APIs to write a local file, request the **ohos.permission.READ_MEDIA** permission by following the instructions provided in [Requesting User Authorization](../../security/AccessToken/request-user-authorization.md).
51e41f4b71Sopenharmony_ci> - You can also use **ResourceManager.getRawFd** to obtain the FD of a file packed in the HAP file. For details, see [ResourceManager API Reference](../../reference/apis-localization-kit/js-apis-resource-manager.md#getrawfd9).
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci### Linking the Dynamic Libraries in the CMake Script
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci``` cmake
56e41f4b71Sopenharmony_citarget_link_libraries(sample PUBLIC libnative_media_codecbase.so)
57e41f4b71Sopenharmony_citarget_link_libraries(sample PUBLIC libnative_media_avdemuxer.so)
58e41f4b71Sopenharmony_citarget_link_libraries(sample PUBLIC libnative_media_avsource.so)
59e41f4b71Sopenharmony_citarget_link_libraries(sample PUBLIC libnative_media_core.so)
60e41f4b71Sopenharmony_ci```
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci> **NOTE**
63e41f4b71Sopenharmony_ci>
64e41f4b71Sopenharmony_ci> The word 'sample' in the preceding code snippet is only an example. Use the actual project directory name.
65e41f4b71Sopenharmony_ci>
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci### How to Develop
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci1. Add the header files.
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ci   ```c++
72e41f4b71Sopenharmony_ci   #include <multimedia/player_framework/native_avdemuxer.h>
73e41f4b71Sopenharmony_ci   #include <multimedia/player_framework/native_avsource.h>
74e41f4b71Sopenharmony_ci   #include <multimedia/player_framework/native_avcodec_base.h>
75e41f4b71Sopenharmony_ci   #include <multimedia/player_framework/native_avformat.h>
76e41f4b71Sopenharmony_ci   #include <multimedia/player_framework/native_avbuffer.h>
77e41f4b71Sopenharmony_ci   #include <fcntl.h>
78e41f4b71Sopenharmony_ci   #include <sys/stat.h>
79e41f4b71Sopenharmony_ci   ```
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci2. Create a resource object.
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci   When using **open** to obtain the FD, convert the value of **filepath** to a [sandbox path](../../file-management/app-sandbox-directory.md#app-sandbox-directory.md#mapping-between-application-sandbox-paths-and-physical-paths) to obtain sandbox resources.
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ci   ```c++
86e41f4b71Sopenharmony_ci   // Create the FD. You must have the read permission on the file handle when opening the file. (filePath indicates the path of the file to be demuxed. The file must exist.)
87e41f4b71Sopenharmony_ci   std::string filePath = "test.mp4";
88e41f4b71Sopenharmony_ci   int fd = open(filePath.c_str(), O_RDONLY);
89e41f4b71Sopenharmony_ci   struct stat fileStatus {};
90e41f4b71Sopenharmony_ci   size_t fileSize = 0;
91e41f4b71Sopenharmony_ci   if (stat(filePath.c_str(), &fileStatus) == 0) {
92e41f4b71Sopenharmony_ci      fileSize = static_cast<size_t>(fileStatus.st_size);
93e41f4b71Sopenharmony_ci   } else {
94e41f4b71Sopenharmony_ci      printf("get stat failed");
95e41f4b71Sopenharmony_ci      return;
96e41f4b71Sopenharmony_ci   }
97e41f4b71Sopenharmony_ci   // Create a source resource object for the FD resource file. If offset is not the start position of the file or size is not the actual file size, the data obtained may be incomplete. Consequently, the source resource object may fail to create or subsequent demuxing may fail.
98e41f4b71Sopenharmony_ci   OH_AVSource *source = OH_AVSource_CreateWithFD(fd, 0, fileSize);
99e41f4b71Sopenharmony_ci   if (source == nullptr) {
100e41f4b71Sopenharmony_ci      printf("create source failed");
101e41f4b71Sopenharmony_ci      return;
102e41f4b71Sopenharmony_ci   }
103e41f4b71Sopenharmony_ci   // (Optional) Create a source resource object for the URI resource file.
104e41f4b71Sopenharmony_ci   // OH_AVSource *source = OH_AVSource_CreateWithURI(uri);
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci   // (Optional) Create a source resource object for the custom data source. Before the operation, you must implement AVSourceReadAt.
107e41f4b71Sopenharmony_ci   // Add g_filePath when OH_AVSource_CreateWithDataSource is used.
108e41f4b71Sopenharmony_ci   // g_filePath = filePath ;
109e41f4b71Sopenharmony_ci   // OH_AVDataSource dataSource = {fileSize, AVSourceReadAt};
110e41f4b71Sopenharmony_ci   // OH_AVSource *source = OH_AVSource_CreateWithDataSource(&dataSource);
111e41f4b71Sopenharmony_ci   ```
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ci   Implement the **AVSourceReadAt** API before creating the resource object.
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci   ```c++
116e41f4b71Sopenharmony_ci   // Add the header file.
117e41f4b71Sopenharmony_ci   #include <fstream>
118e41f4b71Sopenharmony_ci   ```
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ci   ```c++
121e41f4b71Sopenharmony_ci   static std::string g_filePath;
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci   enum MediaDataSourceError : int32_t {
124e41f4b71Sopenharmony_ci      SOURCE_ERROR_IO = -2,
125e41f4b71Sopenharmony_ci      SOURCE_ERROR_EOF = -1
126e41f4b71Sopenharmony_ci   };
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ci   int32_t AVSourceReadAt(OH_AVBuffer *data, int32_t length, int64_t pos)
129e41f4b71Sopenharmony_ci   {
130e41f4b71Sopenharmony_ci      if (data == nullptr) {
131e41f4b71Sopenharmony_ci         printf("AVSourceReadAt : data is nullptr!\n");
132e41f4b71Sopenharmony_ci         return MediaDataSourceError::SOURCE_ERROR_IO;
133e41f4b71Sopenharmony_ci      }
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci      std::ifstream infile(g_filePath, std::ofstream::binary);
136e41f4b71Sopenharmony_ci      if (!infile.is_open()) {
137e41f4b71Sopenharmony_ci         printf("AVSourceReadAt : open file failed! file:%s\n", g_filePath.c_str());
138e41f4b71Sopenharmony_ci         return MediaDataSourceError::SOURCE_ERROR_IO; // Failed to open the file.
139e41f4b71Sopenharmony_ci      }
140e41f4b71Sopenharmony_ci
141e41f4b71Sopenharmony_ci      infile.seekg(0, std::ios::end);
142e41f4b71Sopenharmony_ci      int64_t fileSize = infile.tellg();
143e41f4b71Sopenharmony_ci      if (pos >= fileSize) {
144e41f4b71Sopenharmony_ci         printf("AVSourceReadAt : pos over or equals file size!\n");
145e41f4b71Sopenharmony_ci         return MediaDataSourceError::SOURCE_ERROR_EOF; // pos is already at the end of the file and cannot be read.
146e41f4b71Sopenharmony_ci      }
147e41f4b71Sopenharmony_ci
148e41f4b71Sopenharmony_ci      if (pos + length > fileSize) {
149e41f4b71Sopenharmony_ci         length of length = fileSize - pos; // When the sum of pos and length exceeds the file size, the data from pos to the end of the file is read.
150e41f4b71Sopenharmony_ci      }
151e41f4b71Sopenharmony_ci
152e41f4b71Sopenharmony_ci      infile.seekg(pos, std::ios::beg);
153e41f4b71Sopenharmony_ci      if (length <= 0) {
154e41f4b71Sopenharmony_ci         printf("AVSourceReadAt : raed length less than zero!\n");
155e41f4b71Sopenharmony_ci         return MediaDataSourceError::SOURCE_ERROR_IO;
156e41f4b71Sopenharmony_ci      }
157e41f4b71Sopenharmony_ci      char* buffer = new char[length];
158e41f4b71Sopenharmony_ci      infile.read(buffer, length);
159e41f4b71Sopenharmony_ci      infile.close();
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci      memcpy(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)),
162e41f4b71Sopenharmony_ci         buffer, length);
163e41f4b71Sopenharmony_ci      delete[] buffer;
164e41f4b71Sopenharmony_ci
165e41f4b71Sopenharmony_ci      return length;
166e41f4b71Sopenharmony_ci   }
167e41f4b71Sopenharmony_ci   ```
168e41f4b71Sopenharmony_ci3. Create a demuxer instance.
169e41f4b71Sopenharmony_ci   ```c++
170e41f4b71Sopenharmony_ci   // Create a demuxer for the resource object.
171e41f4b71Sopenharmony_ci   OH_AVDemuxer *demuxer = OH_AVDemuxer_CreateWithSource(source);
172e41f4b71Sopenharmony_ci   if (demuxer == nullptr) {
173e41f4b71Sopenharmony_ci      printf("create demuxer failed");
174e41f4b71Sopenharmony_ci      return;
175e41f4b71Sopenharmony_ci   }
176e41f4b71Sopenharmony_ci   ```
177e41f4b71Sopenharmony_ci4. (Optional) Register a [callback to obtain the media key system information](../../reference/apis-drm-kit/_drm.md#drm_mediakeysysteminfocallback). If the stream is not a DRM stream or the [media key system information](../../reference/apis-drm-kit/_drm.md#drm_mediakeysysteminfo) has been obtained, you can skip this step.
178e41f4b71Sopenharmony_ci
179e41f4b71Sopenharmony_ci   Add the header file.
180e41f4b71Sopenharmony_ci   ```c++
181e41f4b71Sopenharmony_ci   #include <multimedia/drm_framework/native_drm_common.h>
182e41f4b71Sopenharmony_ci   ```
183e41f4b71Sopenharmony_ci   Link the dynamic library in the cmake script.
184e41f4b71Sopenharmony_ci
185e41f4b71Sopenharmony_ci   ``` cmake
186e41f4b71Sopenharmony_ci   target_link_libraries(sample PUBLIC libnative_drm.so)
187e41f4b71Sopenharmony_ci   ```
188e41f4b71Sopenharmony_ci   There are two types of APIs for setting DRM information listeners. The callback function shown in example 1 can return a demuxer instance and therefore is recommended in the scenario where multiple demuxer instances are used. The callback function shown in example 2 does not return a demuxer instance and is applicable to the scenario where a single demuxer instance is used.
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci   Example 1:
191e41f4b71Sopenharmony_ci   ```c++
192e41f4b71Sopenharmony_ci   // Implement the OnDrmInfoChangedWithObj callback.
193e41f4b71Sopenharmony_ci   static void OnDrmInfoChangedWithObj(OH_AVDemuxer *demuxer, DRM_MediaKeySystemInfo *drmInfo)
194e41f4b71Sopenharmony_ci   {
195e41f4b71Sopenharmony_ci      // Parse the media key system information, including the quantity, DRM type, and corresponding PSSH.
196e41f4b71Sopenharmony_ci   }
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ci   Demuxer_MediaKeySystemInfoCallback callback = &OnDrmInfoChangedWithObj;
199e41f4b71Sopenharmony_ci   Drm_ErrCode ret = OH_AVDemuxer_SetDemuxerMediaKeySystemInfoCallback(demuxer, callback);
200e41f4b71Sopenharmony_ci
201e41f4b71Sopenharmony_ci   ```
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci   Example 2:
204e41f4b71Sopenharmony_ci   ```c++
205e41f4b71Sopenharmony_ci   // Implement the OnDrmInfoChanged callback.
206e41f4b71Sopenharmony_ci   static void OnDrmInfoChanged(DRM_MediaKeySystemInfo *drmInfo)
207e41f4b71Sopenharmony_ci   {
208e41f4b71Sopenharmony_ci      // Parse the media key system information, including the quantity, DRM type, and corresponding PSSH.
209e41f4b71Sopenharmony_ci   }
210e41f4b71Sopenharmony_ci
211e41f4b71Sopenharmony_ci   DRM_MediaKeySystemInfoCallback callback = &OnDrmInfoChanged;
212e41f4b71Sopenharmony_ci   Drm_ErrCode ret = OH_AVDemuxer_SetMediaKeySystemInfoCallback(demuxer, callback);
213e41f4b71Sopenharmony_ci   ```
214e41f4b71Sopenharmony_ci
215e41f4b71Sopenharmony_ci   After the callback is invoked, you can call the API to proactively obtain the media key system information (UUID and corresponding PSSH).
216e41f4b71Sopenharmony_ci   ```c++
217e41f4b71Sopenharmony_ci   DRM_MediaKeySystemInfo mediaKeySystemInfo;
218e41f4b71Sopenharmony_ci   OH_AVDemuxer_GetMediaKeySystemInfo(demuxer, &mediaKeySystemInfo);
219e41f4b71Sopenharmony_ci   ```
220e41f4b71Sopenharmony_ci   After obtaining and parsing DRM information, create [MediaKeySystem](../drm/native-drm-mediakeysystem-management.md) and [MediaKeySession](../drm/native-drm-mediakeysession-management.md) instances of the corresponding DRM scheme to obtain a media key. If required, set the audio decryption configuration by following step 4 in [Audio Decoding](./audio-decoding.md#how-to-develop), and set the video decryption configuration by following step 5 [Surface Output in Video Decoding](./video-decoding.md#surface-mode) or step 4 in [Buffer Output in Video Decoding](./video-decoding.md#buffer mode).
221e41f4b71Sopenharmony_ci
222e41f4b71Sopenharmony_ci5. (Optional) Obtain the number of tracks. If you know the track information, skip this step.
223e41f4b71Sopenharmony_ci
224e41f4b71Sopenharmony_ci   ```c++
225e41f4b71Sopenharmony_ci   // Obtain the number of tracks from the file source information. You can call the API to obtain file-level attributes. For details, see Table 1 in Appendix 1.
226e41f4b71Sopenharmony_ci   OH_AVFormat *sourceFormat = OH_AVSource_GetSourceFormat(source);
227e41f4b71Sopenharmony_ci   if (sourceFormat == nullptr) {
228e41f4b71Sopenharmony_ci      printf("get source format failed");
229e41f4b71Sopenharmony_ci      return;
230e41f4b71Sopenharmony_ci   }
231e41f4b71Sopenharmony_ci   int32_t trackCount = 0;
232e41f4b71Sopenharmony_ci   if (!OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &trackCount)) {
233e41f4b71Sopenharmony_ci      printf("get track count from source format failed");
234e41f4b71Sopenharmony_ci      return;
235e41f4b71Sopenharmony_ci   }
236e41f4b71Sopenharmony_ci   OH_AVFormat_Destroy(sourceFormat);
237e41f4b71Sopenharmony_ci   ```
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci6. (Optional) Obtain the track index and format. If you know the track information, skip this step.
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci   ```c++
242e41f4b71Sopenharmony_ci   uint32_t audioTrackIndex = 0;
243e41f4b71Sopenharmony_ci   uint32_t videoTrackIndex = 0;
244e41f4b71Sopenharmony_ci   int32_t w = 0;
245e41f4b71Sopenharmony_ci   int32_t h = 0;
246e41f4b71Sopenharmony_ci   int32_t trackType;
247e41f4b71Sopenharmony_ci   for (uint32_t index = 0; index < (static_cast<uint32_t>(trackCount)); index++) {
248e41f4b71Sopenharmony_ci      // Obtain the track information. You can call the API to obtain track-level attributes. For details, see Table 2 in Appendix.
249e41f4b71Sopenharmony_ci      OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
250e41f4b71Sopenharmony_ci      if (trackFormat == nullptr) {
251e41f4b71Sopenharmony_ci         printf("get track format failed");
252e41f4b71Sopenharmony_ci         return;
253e41f4b71Sopenharmony_ci      }
254e41f4b71Sopenharmony_ci      if (!OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &trackType)) {
255e41f4b71Sopenharmony_ci         printf("get track type from track format failed");
256e41f4b71Sopenharmony_ci         return;
257e41f4b71Sopenharmony_ci      }
258e41f4b71Sopenharmony_ci      static_cast<OH_MediaType>(trackType) == OH_MediaType::MEDIA_TYPE_AUD ? audioTrackIndex = index : videoTrackIndex = index;
259e41f4b71Sopenharmony_ci      // Obtain the width and height of the video track.
260e41f4b71Sopenharmony_ci      if (trackType == OH_MediaType::MEDIA_TYPE_VID) {
261e41f4b71Sopenharmony_ci         if (!OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_WIDTH, &w)) {
262e41f4b71Sopenharmony_ci            printf("get track width from track format failed");
263e41f4b71Sopenharmony_ci            return;
264e41f4b71Sopenharmony_ci         }
265e41f4b71Sopenharmony_ci         if (!OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_HEIGHT, &h)) {
266e41f4b71Sopenharmony_ci            printf("get track height from track format failed");
267e41f4b71Sopenharmony_ci            return;
268e41f4b71Sopenharmony_ci         }
269e41f4b71Sopenharmony_ci      }
270e41f4b71Sopenharmony_ci      OH_AVFormat_Destroy(trackFormat);
271e41f4b71Sopenharmony_ci   }
272e41f4b71Sopenharmony_ci   ```
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ci7. Select a track, from which the demuxer reads data.
275e41f4b71Sopenharmony_ci
276e41f4b71Sopenharmony_ci   ```c++
277e41f4b71Sopenharmony_ci   if(OH_AVDemuxer_SelectTrackByID(demuxer, audioTrackIndex) != AV_ERR_OK){
278e41f4b71Sopenharmony_ci      printf("select audio track failed: %d", audioTrackIndex);
279e41f4b71Sopenharmony_ci      return;
280e41f4b71Sopenharmony_ci   }
281e41f4b71Sopenharmony_ci   if(OH_AVDemuxer_SelectTrackByID(demuxer, videoTrackIndex) != AV_ERR_OK){
282e41f4b71Sopenharmony_ci      printf("select video track failed: %d", videoTrackIndex);
283e41f4b71Sopenharmony_ci      return;
284e41f4b71Sopenharmony_ci   }
285e41f4b71Sopenharmony_ci   // (Optional) Deselect the track.
286e41f4b71Sopenharmony_ci   // OH_AVDemuxer_UnselectTrackByID(demuxer, audioTrackIndex);
287e41f4b71Sopenharmony_ci   ```
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ci8. (Optional) Seek to the specified time for the selected track.
290e41f4b71Sopenharmony_ci
291e41f4b71Sopenharmony_ci   ```c++
292e41f4b71Sopenharmony_ci   // Demuxing is performed from this time.
293e41f4b71Sopenharmony_ci   // Note:
294e41f4b71Sopenharmony_ci   // 1. If OH_AVDemuxer_SeekToTime is called for an MPEG TS file, the target position may be a non-key frame. You can then call OH_AVDemuxer_ReadSampleBuffer to check whether the current frame is a key frame based on the obtained OH_AVCodecBufferAttr. If it is a non-key frame, which causes display issues on the application side, cyclically read the frames until you reach the first key frame, where you can perform processing such as decoding.
295e41f4b71Sopenharmony_ci   // 2. If OH_AVDemuxer_SeekToTime is called for an OGG file, the file seeks to the start of the time interval (second) where the input parameter millisecond is located, which may cause a certain number of frame errors.
296e41f4b71Sopenharmony_ci   OH_AVDemuxer_SeekToTime(demuxer, 0, OH_AVSeekMode::SEEK_MODE_CLOSEST_SYNC);
297e41f4b71Sopenharmony_ci   ```
298e41f4b71Sopenharmony_ci
299e41f4b71Sopenharmony_ci9. Start demuxing and cyclically obtain samples. The code snippet below uses a file that contains audio and video tracks as an example.
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci   A **BufferAttr** object contains the following attributes.
302e41f4b71Sopenharmony_ci   - **size**: sample size.
303e41f4b71Sopenharmony_ci   - **offset**: offset of the data in the AVBuffer. The value is generally 0.
304e41f4b71Sopenharmony_ci   - **pts**: timestamp when the file is muxed.
305e41f4b71Sopenharmony_ci   - **flags**: sample attributes.
306e41f4b71Sopenharmony_ci
307e41f4b71Sopenharmony_ci   | flag | Description|
308e41f4b71Sopenharmony_ci   | -------- | -------- |
309e41f4b71Sopenharmony_ci   | AVCODEC_BUFFER_FLAGS_NONE | Default value.|
310e41f4b71Sopenharmony_ci   | AVCODEC_BUFFER_FLAGS_EOS | End of Stream (EOS). The data is empty.|
311e41f4b71Sopenharmony_ci   | AVCODEC_BUFFER_FLAGS_SYNC_FRAME | IDR frame or I-frame.|
312e41f4b71Sopenharmony_ci   | AVCODEC_BUFFER_FLAGS_INCOMPLETE_FRAME | Incomplete sample. Generally, a complete sample fails to be copied because the buffer is too small.|
313e41f4b71Sopenharmony_ci   | AVCODEC_BUFFER_FLAGS_CODEC_DATA | Frame containing parameter set information.|
314e41f4b71Sopenharmony_ci   | AVCODEC_BUFFER_FLAGS_DISCARD  | Frames that can be discarded.|
315e41f4b71Sopenharmony_ci
316e41f4b71Sopenharmony_ci   ```c++
317e41f4b71Sopenharmony_ci   // Create a buffer to store the data obtained after demuxing.
318e41f4b71Sopenharmony_ci   OH_AVBuffer *buffer = OH_AVBuffer_Create(w * h * 3 >> 1);
319e41f4b71Sopenharmony_ci   if (buffer == nullptr) {
320e41f4b71Sopenharmony_ci      printf("build buffer failed");
321e41f4b71Sopenharmony_ci      return;
322e41f4b71Sopenharmony_ci   }
323e41f4b71Sopenharmony_ci   OH_AVCodecBufferAttr info;
324e41f4b71Sopenharmony_ci   bool videoIsEnd = false;
325e41f4b71Sopenharmony_ci   bool audioIsEnd = false;
326e41f4b71Sopenharmony_ci   int32_t ret;
327e41f4b71Sopenharmony_ci   while (!audioIsEnd || !videoIsEnd) {
328e41f4b71Sopenharmony_ci      // Before calling OH_AVDemuxer_ReadSampleBuffer, call OH_AVDemuxer_SelectTrackByID to select the track from which the demuxer reads data.
329e41f4b71Sopenharmony_ci      // Obtain the audio sample.
330e41f4b71Sopenharmony_ci      if(!audioIsEnd) {
331e41f4b71Sopenharmony_ci         ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, audioTrackIndex, buffer);
332e41f4b71Sopenharmony_ci         if (ret == AV_ERR_OK) {
333e41f4b71Sopenharmony_ci            // Obtain and process the audio sample in the buffer.
334e41f4b71Sopenharmony_ci            OH_AVBuffer_GetBufferAttr(buffer, &info);
335e41f4b71Sopenharmony_ci            printf("audio info.size: %d\n", info.size);
336e41f4b71Sopenharmony_ci            if (info.flags == OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
337e41f4b71Sopenharmony_ci               audioIsEnd = true;
338e41f4b71Sopenharmony_ci            }
339e41f4b71Sopenharmony_ci         }
340e41f4b71Sopenharmony_ci      }
341e41f4b71Sopenharmony_ci      if(!videoIsEnd) {
342e41f4b71Sopenharmony_ci         ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, videoTrackIndex, buffer);
343e41f4b71Sopenharmony_ci         if (ret == AV_ERR_OK) {
344e41f4b71Sopenharmony_ci            // Obtain and process the video sample in the buffer.
345e41f4b71Sopenharmony_ci            OH_AVBuffer_GetBufferAttr(buffer, &info);
346e41f4b71Sopenharmony_ci            printf("video info.size: %d\n", info.size);
347e41f4b71Sopenharmony_ci            if (info.flags == OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
348e41f4b71Sopenharmony_ci               videoIsEnd = true;
349e41f4b71Sopenharmony_ci            }
350e41f4b71Sopenharmony_ci         }
351e41f4b71Sopenharmony_ci      }
352e41f4b71Sopenharmony_ci   }
353e41f4b71Sopenharmony_ci   OH_AVBuffer_Destroy(buffer);
354e41f4b71Sopenharmony_ci   ```
355e41f4b71Sopenharmony_ci
356e41f4b71Sopenharmony_ci10. Destroy the demuxer instance.
357e41f4b71Sopenharmony_ci      ```c++
358e41f4b71Sopenharmony_ci      // Manually set the instance to NULL after OH_AVSource_Destroy is called. Do not call this API repeatedly for the same instance; otherwise, a program error occurs.
359e41f4b71Sopenharmony_ci      if (OH_AVSource_Destroy(source) != AV_ERR_OK) {
360e41f4b71Sopenharmony_ci         printf("destroy source pointer error");
361e41f4b71Sopenharmony_ci      }
362e41f4b71Sopenharmony_ci      source = NULL;
363e41f4b71Sopenharmony_ci      // Manually set the instance to NULL after OH_AVDemuxer_Destroy is called. Do not call this API repeatedly for the same instance; otherwise, a program error occurs.
364e41f4b71Sopenharmony_ci      if (OH_AVDemuxer_Destroy(demuxer) != AV_ERR_OK) {
365e41f4b71Sopenharmony_ci         printf("destroy demuxer pointer error");
366e41f4b71Sopenharmony_ci      }
367e41f4b71Sopenharmony_ci      demuxer = NULL;
368e41f4b71Sopenharmony_ci      close(fd);
369e41f4b71Sopenharmony_ci      ```
370e41f4b71Sopenharmony_ci
371e41f4b71Sopenharmony_ci## Appendix
372e41f4b71Sopenharmony_ci### Supported File-Level Attributes
373e41f4b71Sopenharmony_ci
374e41f4b71Sopenharmony_ci> **NOTE**
375e41f4b71Sopenharmony_ci>
376e41f4b71Sopenharmony_ci> Attribute data can be obtained only when the file is parsed normally. If the file information is incorrect or missing, the parsing is abnormal and the corresponding data cannot be obtained.
377e41f4b71Sopenharmony_ci> 
378e41f4b71Sopenharmony_ci> For details about the data type and value range, see [Media Data Key-Value Pairs](../../reference/apis-avcodec-kit/_codec_base.md#media-data-key-value-pairs).
379e41f4b71Sopenharmony_ci
380e41f4b71Sopenharmony_ci**Table 1** Supported file-level attributes
381e41f4b71Sopenharmony_ci| Name| Description|
382e41f4b71Sopenharmony_ci| -- | -- |
383e41f4b71Sopenharmony_ci|OH_MD_KEY_TITLE|Title.|
384e41f4b71Sopenharmony_ci|OH_MD_KEY_ARTIST|Artist.|
385e41f4b71Sopenharmony_ci|OH_MD_KEY_ALBUM|Album.|
386e41f4b71Sopenharmony_ci|OH_MD_KEY_ALBUM_ARTIST|Album artist.|
387e41f4b71Sopenharmony_ci|OH_MD_KEY_DATE|Date.|
388e41f4b71Sopenharmony_ci|OH_MD_KEY_COMMENT|Comment.|
389e41f4b71Sopenharmony_ci|OH_MD_KEY_GENRE|Genre.|
390e41f4b71Sopenharmony_ci|OH_MD_KEY_COPYRIGHT|Copyright.|
391e41f4b71Sopenharmony_ci|OH_MD_KEY_LANGUAGE|Language.|
392e41f4b71Sopenharmony_ci|OH_MD_KEY_DESCRIPTION|Description.|
393e41f4b71Sopenharmony_ci|OH_MD_KEY_LYRICS|Lyrics.|
394e41f4b71Sopenharmony_ci|OH_MD_KEY_TRACK_COUNT|Track count.|
395e41f4b71Sopenharmony_ci|OH_MD_KEY_DURATION|Duration.|
396e41f4b71Sopenharmony_ci|OH_MD_KEY_START_TIME|Start time.|
397e41f4b71Sopenharmony_ci
398e41f4b71Sopenharmony_ci### Supported Track-Level Attributes
399e41f4b71Sopenharmony_ci
400e41f4b71Sopenharmony_ci> **NOTE**
401e41f4b71Sopenharmony_ci>
402e41f4b71Sopenharmony_ci> Attribute data can be obtained only when the file is parsed normally. If the file information is incorrect or missing, the parsing is abnormal and the corresponding data cannot be obtained.
403e41f4b71Sopenharmony_ci> 
404e41f4b71Sopenharmony_ci> For details about the data type and value range, see [Media Data Key-Value Pairs](../../reference/apis-avcodec-kit/_codec_base.md#media-data-key-value-pairs).
405e41f4b71Sopenharmony_ci
406e41f4b71Sopenharmony_ci**Table 2** Supported track-level attributes
407e41f4b71Sopenharmony_ci| Name| Description| Supported by Video Tracks| Supported by Audio Tracks| Supported by Subtitle Tracks|
408e41f4b71Sopenharmony_ci| -- | -- | -- | -- | -- |
409e41f4b71Sopenharmony_ci|OH_MD_KEY_CODEC_MIME|Stream codec type.|Supported|Supported|Supported|
410e41f4b71Sopenharmony_ci|OH_MD_KEY_TRACK_TYPE|Stream track type.|Supported|Supported|Supported|
411e41f4b71Sopenharmony_ci|OH_MD_KEY_TRACK_START_TIME|Start time of the stream.|Supported|Supported|Supported|
412e41f4b71Sopenharmony_ci|OH_MD_KEY_BITRATE|Stream bit rate.|Supported|Supported|Not supported|
413e41f4b71Sopenharmony_ci|OH_MD_KEY_LANGUAGE|Stream language type.|Supported|Supported|Not supported|
414e41f4b71Sopenharmony_ci|OH_MD_KEY_CODEC_CONFIG|Codec-specific data. In the case of video, a parameter set is transferred. In the case of audio, parameter configuration information of the decoder is transferred.|Supported|Supported|Not supported|
415e41f4b71Sopenharmony_ci|OH_MD_KEY_WIDTH|Video stream width.|Supported|Not supported|Not supported|
416e41f4b71Sopenharmony_ci|OH_MD_KEY_HEIGHT|Video stream height.|Supported|Not supported|Not supported|
417e41f4b71Sopenharmony_ci|OH_MD_KEY_FRAME_RATE|Video stream frame rate.|Supported|Not supported|Not supported|
418e41f4b71Sopenharmony_ci|OH_MD_KEY_ROTATION|Rotation angle of the video stream.|Supported|Not supported|Not supported|
419e41f4b71Sopenharmony_ci|OH_MD_KEY_VIDEO_SAR|Aspect ratio of the video stream sample.|Supported|Not supported|Not supported|
420e41f4b71Sopenharmony_ci|OH_MD_KEY_PROFILE|Encoding profile of the video stream. This key is valid only for H.265 streams.|Supported|Not supported|Not supported|
421e41f4b71Sopenharmony_ci|OH_MD_KEY_RANGE_FLAG|Video YUV value range flag of the video stream. This key is valid only for H.265 streams.|Supported|Not supported|Not supported|
422e41f4b71Sopenharmony_ci|OH_MD_KEY_COLOR_PRIMARIES|Video primary color of the video stream. This key is valid only for H.265 streams.|Supported|Not supported|Not supported|
423e41f4b71Sopenharmony_ci|OH_MD_KEY_TRANSFER_CHARACTERISTICS|Video transfer characteristics of the video stream. This key is valid only for H.265 streams.|Supported|Not supported|Not supported|
424e41f4b71Sopenharmony_ci|OH_MD_KEY_MATRIX_COEFFICIENTS|Video matrix coefficient. This key is valid only for H.265 streams.|Supported|Not supported|Not supported|
425e41f4b71Sopenharmony_ci|OH_MD_KEY_VIDEO_IS_HDR_VIVID|Flag indicating whether the video stream is HDR Vivid. This key is valid only for HDR Vivid streams.|Supported|Not supported|Not supported|
426e41f4b71Sopenharmony_ci|OH_MD_KEY_AUD_SAMPLE_RATE|Audio stream sampling rate.|Not supported|Supported|Not supported|
427e41f4b71Sopenharmony_ci|OH_MD_KEY_AUD_CHANNEL_COUNT|Number of audio stream channels.|Not supported|Supported|Not supported|
428e41f4b71Sopenharmony_ci|OH_MD_KEY_CHANNEL_LAYOUT|Encoding channel layout required by the audio stream.|Not supported|Supported|Not supported|
429e41f4b71Sopenharmony_ci|OH_MD_KEY_AUDIO_SAMPLE_FORMAT|Audio stream sample format.|Not supported|Supported|Not supported|
430e41f4b71Sopenharmony_ci|OH_MD_KEY_AAC_IS_ADTS|AAC format. This key is valid only for AAC streams.|Not supported|Supported|Not supported|
431e41f4b71Sopenharmony_ci|OH_MD_KEY_BITS_PER_CODED_SAMPLE|Number of bits per coded sample in the audio stream.|Not supported|Supported|Not supported|
432