@@ -335,6 +335,196 @@ static PyObject* get_enum(const char* const name, const biguint_t value) {
335
335
336
336
}
337
337
338
+ static PyObject * get_segments (const struct M3U8Stream * const stream ) {
339
+
340
+ size_t index = 0 ;
341
+ size_t subindex = 0 ;
342
+
343
+ int status = 0 ;
344
+ int err = M3U8ERR_SUCCESS ;
345
+
346
+ const struct M3U8BaseURI * const base_uri = m3u8playlist_geturi (& stream -> playlist );
347
+
348
+ char * resolved_uri = NULL ;
349
+
350
+ PyObject * key = NULL ;
351
+
352
+ PyObject * method = NULL ;
353
+ PyObject * uri = NULL ;
354
+ PyObject * iv = NULL ;
355
+ PyObject * keyformat = NULL ;
356
+ PyObject * keyformatversions = NULL ;
357
+ PyObject * tag = NULL ;
358
+ PyObject * duration = NULL ;
359
+ PyObject * title = NULL ;
360
+ PyObject * byterange = NULL ;
361
+
362
+
363
+
364
+ PyObject * version = NULL ;
365
+
366
+ PyObject * segments = PyList_New (0 );
367
+
368
+ PyObject * class = NULL ;
369
+ PyObject * args = NULL ;
370
+
371
+ PyObject * module = NULL ;
372
+
373
+ module = PyImport_ImportModule ("kai" );
374
+
375
+ if (module == NULL ) {
376
+ return NULL ;
377
+ }
378
+
379
+ if (segments == NULL ) {
380
+ return NULL ;
381
+ }
382
+
383
+ for (index = 0 ; index < stream -> offset ; index ++ ) {
384
+ const struct M3U8StreamItem * const item = & stream -> items [index ];
385
+
386
+ if (!(item -> type == M3U8_STREAM_SEGMENT || item -> type == M3U8_STREAM_MAP )) {
387
+ continue ;
388
+ }
389
+
390
+ switch (item -> type ) {
391
+ case M3U8_STREAM_SEGMENT : {
392
+ const struct M3U8Segment * const segment = ((struct M3U8Segment * ) item -> item );
393
+
394
+ /* Key */
395
+ key = Py_None ;
396
+
397
+ if (segment -> key .uri != NULL ) {
398
+ /* Key -> Method */
399
+ method = get_enum ("M3U8EncryptionMethod" , segment -> key .method );
400
+
401
+ if (method == NULL ) {
402
+ return NULL ;
403
+ }
404
+
405
+ /* Key -> URI */
406
+ free (resolved_uri );
407
+
408
+ err = m3u8uri_resolve (base_uri , segment -> key .uri , & resolved_uri );
409
+
410
+ uri = get_string ((err == M3U8ERR_SUCCESS ) ? resolved_uri : segment -> key .uri );
411
+
412
+ if (uri == NULL ) {
413
+ return NULL ;
414
+ }
415
+
416
+ /* Key -> IV */
417
+ iv = Py_None ;
418
+
419
+ if (segment -> key .iv .offset > 0 ) {
420
+ iv = PyByteArray_FromStringAndSize (
421
+ segment -> key .iv .data ,
422
+ segment -> key .iv .offset
423
+ );
424
+ }
425
+
426
+ if (iv == NULL ) {
427
+ return NULL ;
428
+ }
429
+
430
+ /* Key -> Key format */
431
+ keyformat = get_string (segment -> key .keyformat );
432
+
433
+ if (keyformat == NULL ) {
434
+ return NULL ;
435
+ }
436
+
437
+ /* Key -> Key format versions */
438
+ keyformatversions = Py_None ;
439
+
440
+ if (segment -> key .keyformatversions .offset > 0 ) {
441
+ keyformatversions = PyList_New (segment -> key .keyformatversions .offset );
442
+
443
+ if (keyformatversions == NULL ) {
444
+ return NULL ;
445
+ }
446
+
447
+ for (subindex = 0 ; subindex < segment -> key .keyformatversions .offset ; subindex ++ ) {
448
+ const int value = segment -> key .keyformatversions .items [subindex ];
449
+
450
+ PyObject * item = PyBool_FromLong (value );
451
+
452
+ if (item == NULL ) {
453
+ return NULL ;
454
+ }
455
+
456
+ status = PyList_SetItem (keyformatversions , subindex , item );
457
+
458
+ if (status != 0 ) {
459
+ return NULL ;
460
+ }
461
+ }
462
+ }
463
+
464
+ /* Key -> Tag */
465
+ tag = PyLong_FromLongLong ((uintptr_t ) segment -> key .tag );
466
+
467
+ if (tag == NULL ) {
468
+ return NULL ;
469
+ }
470
+
471
+ class = PyObject_GetAttrString (module , "M3U8Key" );
472
+
473
+ if (class == NULL ) {
474
+ return NULL ;
475
+ }
476
+
477
+ args = Py_BuildValue (
478
+ "(OOOOOO)" ,
479
+ method ,
480
+ uri ,
481
+ iv ,
482
+ keyformat ,
483
+ keyformatversions ,
484
+ tag
485
+ );
486
+
487
+ if (args == NULL ) {
488
+ return NULL ;
489
+ }
490
+
491
+ key = PyObject_Call (class , args , NULL );
492
+
493
+ Py_DECREF (class );
494
+ Py_DECREF (args );
495
+ }
496
+
497
+ if (key == NULL ) {
498
+ return NULL ;
499
+ }
500
+
501
+ /* Duration */
502
+ duration = PyLong_FromLongLong (segment -> duration );
503
+
504
+ if (duration == NULL ) {
505
+ return NULL ;
506
+ }
507
+
508
+ /* Title */
509
+ title = get_string (segment -> title );
510
+
511
+ if (title == NULL ) {
512
+ return NULL ;
513
+ }
514
+
515
+ /* Byte range */
516
+ byterange = Py_None
517
+ }
518
+ case M3U8_STREAM_MAP : {
519
+ const struct M3U8Map * const map = ((struct M3U8Map * ) item -> item );
520
+ }
521
+ default :
522
+ break ;
523
+ }
524
+ }
525
+
526
+ }
527
+
338
528
static PyObject * topy (
339
529
const struct M3U8Stream * const root ,
340
530
const struct M3U8StreamItem * const item
0 commit comments