Guest User

Untitled

a guest
May 14th, 2026
7
0
358 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     //***********************************
  2.     //    Better WebM title parsing
  3.     //***********************************
  4.     // differences with the 2ch version:
  5.     // - finds title text in more webms
  6.     // - can handle cp1251 encoded text
  7.     // Fails when bytes are made from text.encode('utf-8').decode('cp1251').encode('utf-8')
  8.  
  9.     const decodeText = (function() {
  10.         if (!window.TextDecoder) {
  11.             // "fancy" utf-8 decoder, see:
  12.             // https://stackoverflow.com/a/13691499
  13.             return function decodeUTF8(bytes) {
  14.                 try {
  15.                     return decodeURIComponent(escape(String.fromCharCode.apply(0, bytes)));
  16.                 } catch(e) {
  17.                     console.warn('failed to decode webm title', bytes, e);
  18.                     return null;
  19.                 }
  20.             }
  21.         }
  22.  
  23.         const encodings = [ 'utf-8', 'cp1251' ];
  24.         const options = { fatal: true };
  25.         const decoders = encodings.map(e => new TextDecoder(e, options));
  26.  
  27.         return function decodeText(bytes) {
  28.             for (const decoder of decoders) {
  29.                 try {
  30.                     return decoder.decode(bytes);
  31.                 } catch(e) {
  32.                     continue;
  33.                 }
  34.             }
  35.  
  36.             console.warn('failed to decode webm title', bytes);
  37.             return null;
  38.         }
  39.     })();
  40.  
  41.  
  42.     // const MATROSKA_ID_SEGMENT = 0x18538067;
  43.     const MATROSKA_ID_INFO = 0x1549A966;
  44.     const MATROSKA_ID_TITLE = 0x7BA9;
  45.     const MATROSKA_ID_MUXINGAPP = 0x4D80;
  46.     const MATROSKA_ID_SEEK_POS = 0x53AC;
  47.  
  48.     MediaDataParser.prototype.getWebmTitle = function getWebmTitle() {
  49.         const data = new DataView(this.data);
  50.         const dataEnd = data.byteLength - 4;
  51.  
  52.         for (let i = 0; i < dataEnd; i++) {
  53.             if (data.getUint32(i) === MATROSKA_ID_INFO) {
  54.                 if (data.getUint16(i + 4) === MATROSKA_ID_SEEK_POS) {
  55.                     continue;
  56.                 }
  57.  
  58.                 for (i += 4; i < dataEnd; i++) {
  59.                     let tag = data.getUint16(i);
  60.  
  61.                     if (tag === MATROSKA_ID_TITLE) {
  62.                         // |i:id_tag|i + 2:length|i + 3:bytes|
  63.                         const bytes = new Uint8Array(this.data, i + 3, data.getUint8(i + 2) & 0x7F);
  64.                         return decodeText(bytes) ?? ':: non-utf8 garbage ::';
  65.                     }
  66.  
  67.                     if (tag === MATROSKA_ID_MUXINGAPP) {
  68.                         // title not found, search the next info segment
  69.                         break;
  70.                     }
  71.                 }
  72.             }
  73.         }
  74.  
  75.         return '';
  76.     }
  77.  
Add Comment
Please, Sign In to add comment