@@ -52,10 +52,21 @@ def metadata_pages(self, pages: Optional[List[UsmPage]]):
52
52
def channel_number (self ) -> int :
53
53
return self ._channel_number
54
54
55
+ @channel_number .setter
56
+ def channel_number (self , new_channel_number : int ):
57
+ if new_channel_number < 0 :
58
+ raise ValueError (f"Given negative channel number: { new_channel_number } " )
59
+
60
+ self ._channel_number = new_channel_number
61
+
55
62
@property
56
63
def header_page (self ) -> UsmPage :
57
64
return self ._header_page
58
65
66
+ @header_page .setter
67
+ def header_page (self , new_header_page : UsmPage ):
68
+ self ._header_page = new_header_page
69
+
59
70
@property
60
71
def filename (self ) -> str :
61
72
"""A slugified filename, which is stored inside the crid_page.
@@ -68,6 +79,12 @@ def filename(self) -> str:
68
79
result : str = filename .val .split ("/" )[- 1 ]
69
80
return slugify (result , allow_unicode = True )
70
81
82
+ @filename .setter
83
+ def filename (self , new_filename : str ):
84
+ new_filename = slugify (new_filename , allow_unicode = True )
85
+ self .crid_page ["filename" ].type = ElementType .STRING
86
+ self .crid_page ["filename" ].val = new_filename
87
+
71
88
def __len__ (self ) -> int :
72
89
"""The number of packets a Usm videos or audios has."""
73
90
return self ._length
@@ -89,6 +106,7 @@ class UsmVideo(UsmMedia, Protocol):
89
106
# Classes that explicitly inherit UsmVideo should have this attribute
90
107
# to use the default stream and chunks methods.
91
108
_stream : Generator [Tuple [bytes , bool ], None , None ]
109
+ is_alpha : bool
92
110
93
111
def stream (
94
112
self , mode : OpMode = OpMode .NONE , key : Optional [bytes ] = None
@@ -317,246 +335,3 @@ def chunks(
317
335
channel_number = self .channel_number ,
318
336
),
319
337
]
320
-
321
-
322
- # TODO: Delete the comments when done rewriting
323
-
324
- # class VP9:
325
- # def __init__(self, filepath: str):
326
- # self.filename = os.path.basename(filepath)
327
- # self.filesize = os.path.getsize(filepath)
328
- # self.info = ffmpeg.probe(filepath, show_entries="packet=dts,pts_time,pos,flags")
329
-
330
- # if len(self.info.get("streams")) == 0:
331
- # raise Exception("No streams found")
332
- # elif len(self.info.get("streams")) > 1:
333
- # raise NotImplementedError("Can only accept one stream")
334
- # elif self.info.get("format").get("format_name") != "ivf":
335
- # raise Exception("Not an ivf file")
336
- # elif self.info.get("streams")[0].get("codec_name") != "vp9":
337
- # raise Exception("Not a VP9 videos")
338
-
339
- # video_stream = self.info.get("streams")[0]
340
- # self.bitrate = int(self.info.get("format").get("bit_rate"))
341
- # self.width = int(video_stream.get("width"))
342
- # self.height = int(video_stream.get("height"))
343
- # self.framerate_n = int(video_stream.get("r_frame_rate").split("/")[0])
344
- # self.framerate_d = int(video_stream.get("r_frame_rate").split("/")[1])
345
-
346
- # self.frames = self.info.get("packets")
347
- # self.keyframes = [frame for frame in self.frames if frame.get("flags") == "K_"]
348
- # self.total_frames = len(self.frames)
349
- # self.file = open(filepath, "rb")
350
-
351
- # def export(
352
- # self, encrypt: bool, key: Optional[int] = None, encoding: str = "UTF-8"
353
- # ) -> bytes:
354
- # if encrypt:
355
- # video_key1, video_key2, _ = generate_keys(key)
356
-
357
- # debug = open("FRAME_TIME_DEBUG", "w+")
358
- # stream_chunks = bytearray()
359
- # keyframe_usm_offsets = []
360
- # max_frame_size = 0
361
- # max_packed_frame_size = 0
362
- # max_keyframe_to_keyframe_size = 0
363
- # current_keyframe_to_keyframe_size = 0
364
- # self.file.seek(0, 0)
365
- # for i, frame in enumerate(self.frames):
366
- # # frame_time formula is based on existing usm files.
367
- # # TODO: Does this hold up for videos that's not 30fps?
368
- # debug.write("Frame {}: time = {}".format(i, frame.get("pts_time")))
369
- # # frame_time = int(99.86891 * i)
370
- # frame_time = int(i * 99.9)
371
- # if frame in self.keyframes:
372
- # keyframe_usm_offsets.append(len(stream_chunks))
373
-
374
- # if i == len(self.frames) - 1:
375
- # # Last frame
376
- # frame_size = self.filesize - int(frame.get("pos"))
377
- # else:
378
- # frame_size = int(self.frames[i + 1].get("pos")) - int(frame.get("pos"))
379
-
380
- # if i == 0:
381
- # # Include 32 byte header for first frame
382
- # max_frame_size = frame_size + 32
383
- # packet = self.file.read(frame_size + 32)
384
- # else:
385
- # if frame_size > max_frame_size:
386
- # max_frame_size = frame_size
387
-
388
- # packet = self.file.read(frame_size)
389
-
390
- # if frame.get("flags") != "K_":
391
- # current_keyframe_to_keyframe_size += frame_size
392
- # elif current_keyframe_to_keyframe_size > max_keyframe_to_keyframe_size:
393
- # max_keyframe_to_keyframe_size = current_keyframe_to_keyframe_size
394
- # current_keyframe_to_keyframe_size = frame_size
395
-
396
- # if encrypt:
397
- # packet = encrypt_video_packet(packet, video_key1, video_key2)
398
-
399
- # padding_size = 0x20 - (len(packet) % 0x20) if len(packet) % 0x20 != 0 else 0
400
- # packed_frame_chunk = generate_packed_chunk(
401
- # "@SFV",
402
- # 0,
403
- # int(100 * self.framerate_n / self.framerate_d),
404
- # frame_time,
405
- # packet,
406
- # padding_size,
407
- # )
408
- # if len(packed_frame_chunk) > max_packed_frame_size:
409
- # max_packed_frame_size = len(packed_frame_chunk)
410
-
411
- # stream_chunks += packed_frame_chunk
412
-
413
- # stream_chunks += generate_packed_chunk(
414
- # "@SFV",
415
- # 2,
416
- # int(self.framerate_n / self.framerate_d),
417
- # 0,
418
- # bytes("#CONTENTS END ===============", "UTF-8") + bytes(1),
419
- # 0,
420
- # )
421
-
422
- # seek_chunks = bytearray()
423
- # keyframe_pages = []
424
- # video_header_end_offset = get_video_header_end_offset(len(self.keyframes))
425
- # # Offset of videos header end offset plus length of videos header end
426
- # stream_offset = video_header_end_offset + 0x40
427
- # for i, keyframe in enumerate(self.keyframes):
428
- # keyframe_usm_offset = keyframe_usm_offsets[i]
429
- # keyframe_offset = stream_offset + keyframe_usm_offset
430
- # keyframe_page = UsmPage("VIDEO_SEEKINFO", i)
431
- # keyframe_page.add("ofs_byte", ElementType.clonglong, keyframe_offset)
432
- # keyframe_page.add("ofs_frmid", ElementType.cuint, keyframe.get("dts"))
433
- # keyframe_page.add("num_skip", ElementType.cushort, 0)
434
- # keyframe_page.add("resv", ElementType.cushort, 0)
435
- # keyframe_pages.append(keyframe_page)
436
-
437
- # seek_chunks_payload = pack_pages(keyframe_pages, string_padding=1)
438
- # # 0x20 bytes for chunk header.
439
- # seek_chunks_padding = (
440
- # video_header_end_offset - 0xA40 - 0x20 - len(seek_chunks_payload)
441
- # )
442
- # seek_chunks += generate_packed_chunk(
443
- # "@SFV",
444
- # 3,
445
- # int(self.framerate_n / self.framerate_d),
446
- # 0,
447
- # seek_chunks_payload,
448
- # seek_chunks_padding,
449
- # )
450
- # metadata_size = len(seek_chunks)
451
- # seek_chunks += generate_packed_chunk(
452
- # "@SFV",
453
- # 2,
454
- # int(self.framerate_n / self.framerate_d),
455
- # 0,
456
- # bytes("#METADATA END ===============", "UTF-8") + bytes(1),
457
- # 0,
458
- # )
459
-
460
- # header_page = UsmPage("VIDEO_HDRINFO", 0)
461
- # header_page.add("width", ElementType.cint, self.width)
462
- # header_page.add("height", ElementType.cint, self.height)
463
- # header_page.add("mat_width", ElementType.cint, self.width)
464
- # header_page.add("mat_height", ElementType.cint, self.height)
465
- # header_page.add("disp_width", ElementType.cint, self.width)
466
- # header_page.add("disp_height", ElementType.cint, self.height)
467
- # header_page.add("scrn_width", ElementType.cint, 0)
468
- # header_page.add("mpeg_dcprec", ElementType.cchar, 0)
469
- # header_page.add("mpeg_codec", ElementType.cchar, 9)
470
- # # TODO: Check if videos has transparency
471
- # header_page.add("alpha_type", ElementType.cint, 0)
472
- # header_page.add("total_frames", ElementType.cint, self.total_frames)
473
-
474
- # framerate_n = self.framerate_n
475
- # framerate_d = self.framerate_d
476
-
477
- # if framerate_d < 1000 and framerate_d != 1000:
478
- # framerate_d *= 1000
479
- # framerate_n *= 1000
480
-
481
- # header_page.add("framerate_n", ElementType.cint, framerate_n)
482
- # header_page.add("framerate_d", ElementType.cint, framerate_d)
483
- # header_page.add("metadata_count", ElementType.cint, 1)
484
- # header_page.add("metadata_size", ElementType.cint, metadata_size)
485
- # header_page.add("ixsize", ElementType.cint, max_packed_frame_size)
486
- # header_page.add("pre_padding", ElementType.cint, 0)
487
- # header_page.add("max_picture_size", ElementType.cint, 0)
488
- # header_page.add("color_space", ElementType.cint, 0)
489
- # header_page.add("picture_type", ElementType.cint, 0)
490
-
491
- # header_chunk_payload = pack_pages([header_page])
492
- # header_chunk_padding = 0xA00 - 0x800 - 0x20 - len(header_chunk_payload)
493
- # header_chunk = bytearray()
494
- # header_chunk += generate_packed_chunk(
495
- # "@SFV",
496
- # 1,
497
- # int(self.framerate_n / self.framerate_d),
498
- # 0,
499
- # header_chunk_payload,
500
- # header_chunk_padding,
501
- # )
502
- # header_chunk += generate_packed_chunk(
503
- # "@SFV",
504
- # 2,
505
- # int(self.framerate_n / self.framerate_d),
506
- # 0,
507
- # bytes("#HEADER END ===============", "UTF-8") + bytes(1),
508
- # 0,
509
- # )
510
-
511
- # directory_pages = []
512
- # for i in range(0, 2):
513
- # if i == 0:
514
- # filename = os.path.splitext(self.filename)[0] + ".usm"
515
- # # filename = r"I:\000125 千本桜\000125.usm"
516
- # filesize = (
517
- # 0x800 + len(header_chunk) + len(seek_chunks) + len(stream_chunks)
518
- # )
519
- # stmid = 0
520
- # chno = -1
521
- # minchk = 1
522
- # # TODO: Find formula for minbuf for usm
523
- # minbuf = round(1.98746 * max_frame_size)
524
- # minbuf += 0x10 - (minbuf % 0x10) if minbuf % 0x10 != 0 else 0
525
- # else:
526
- # filename = self.filename
527
- # # filename = r"I:\000125 千本桜\000125.ivf"
528
-
529
- # filesize = self.filesize
530
- # stmid = 1079199318 # @SFV
531
- # chno = 0
532
- # minchk = 3
533
- # minbuf = max_frame_size
534
-
535
- # directory_part = UsmPage("CRIUSF_DIR_STREAM", 0)
536
- # directory_part.add("fmtver", ElementType.cint, 16777984)
537
- # directory_part.add("filename", ElementType.cstring, filename)
538
- # directory_part.add("filesize", ElementType.cint, filesize)
539
- # directory_part.add("datasize", ElementType.cint, 0)
540
- # directory_part.add("stmid", ElementType.cint, stmid)
541
- # directory_part.add("chno", ElementType.cshort, chno)
542
- # directory_part.add("minchk", ElementType.cshort, minchk)
543
- # directory_part.add("minbuf", ElementType.cint, minbuf)
544
- # directory_part.add("avbps", ElementType.cint, self.bitrate)
545
- # directory_pages.append(directory_part)
546
-
547
- # directory_chunk_payload = pack_pages(directory_pages, encoding, 5)
548
- # directory_chunk_padding = 0x800 - 0x20 - len(directory_chunk_payload)
549
- # directory_chunk = bytearray()
550
- # directory_chunk += generate_packed_chunk(
551
- # "CRID",
552
- # 1,
553
- # int(self.framerate_n / self.framerate_d),
554
- # 0,
555
- # directory_chunk_payload,
556
- # directory_chunk_padding,
557
- # )
558
- # result = directory_chunk + header_chunk + seek_chunks + stream_chunks
559
- # return bytes(result)
560
-
561
- # def close(self):
562
- # self.file.close()
0 commit comments