Formato para ID do vídeo do YouTube

32

Todo vídeo do YouTube tem um ID exclusivo que pode ser usado para isso. Por exemplo, o vídeo em http://www.youtube.com/watch?v=aN46pEO_jX8tem o ID aN46pEO_jX8.

Após algumas observações, parece-me que esses IDs obedecem às duas regras a seguir:

  • Exatamente 11 caracteres
  • Símbolos permitidos: az, AZ, 0-9, - e _

Eu quero saber:

  1. Se essas duas regras estão sempre sempre corretas.
  2. Se houver outras regras importantes a serem seguidas.
asfallows
fonte

Respostas:

38

De acordo com a documentação da API do YouTube 2.0 e a documentação da API 3.0 , o videoId é uma string, nada é especificado sobre o conjunto atual de caracteres usado ...

Com cerca de 11 caracteres, uma postagem de uma equipe da API do YouTube diz:

Não vejo nenhum lugar na documentação em que nos comprometemos oficialmente a um tamanho padrão de 11 caracteres para os IDs de vídeo do YouTube. É uma daquelas coisas em que temos uma implementação atual e pode permanecer assim indefinidamente. Mas não estamos oferecendo nenhum compromisso oficial com isso, portanto, prossiga por seu próprio risco.

E por último mas não menos importante, outro post esclarece (ou não) o formato:

Não oferecemos garantias públicas sobre o formato dos IDs de vídeo. Embora atualmente sejam 11 cadeias de caracteres que contenham letras, números e alguma pontuação, eu não recomendaria que o codificasse no seu aplicativo (a menos que você tenha uma maneira fácil de alterá-lo no futuro).

A equipe do YouTube parece preferir perguntar diretamente ao servidor do Youtube se o Video_ID está correto ou não (consulte um vídeo existente):

Se você precisar validar que a entrada aleatória do usuário corresponde a um ID de vídeo válido, recomendo fazer um teste empírico. Tentativa de acesso

http://gdata.youtube.com/feeds/api/videos/VIDEO_ID

Se você receber uma resposta de 200, VIDEO_ID é válido. Se você receber uma resposta que não seja 200, você tem um ID inválido. Existem alguns casos extremos de vídeos recém-enviados ou de vídeos privados, mas, para a maioria dos propósitos, eu suporia que tudo ficaria bem.

Cédric Julien
fonte
Esta é uma ótima resposta e me deu todas as informações que eu precisava! Obrigado!
asfallows
3
Isso retorna um HTTP 410 removido agora. Alguma idéia de qual deve ser o novo URL para verificar isso agora?
Will Strohl
1
Para verificar o ID do vídeo: basta obter a página html do youtube e verificar se o link meta canônico tem o mesmo ID que você especificou.
puchu
50

Os identificadores videoId e channelId do YouTube são valores inteiros únicos representados em uma versão ligeiramente modificada da codificação Base64 . Uma diferença em relação às recomendações IETF RFC4648 é a substituição de dois caracteres no alfabeto de codificação:

 Payload  ASCII/Unicode      Base64     YouTube
 -------  -------------     ---------  ---------
  0...25  \x41 ... \x5A     'A'...'Z'  'A'...'Z'
 26...51  \x61 ... \x7A     'a'...'z'  'a'...'z'
 52...61  \x30 ... \x39     '0'...'9'  '0'...'9'
    62    \x2F vs. \x2D  →   '/' (2F)   '-' (2D)
    63    \x2B vs. \x5F  →   '+' (2B)   '_' (5F)

A substituição provavelmente se deve ao fato de que, por algum motivo, o RFC4648 selecionou dois caracteres que já tinham funções importantes e bem estabelecidas nos URLs. [nota 1.] Obviamente, para o uso discutido aqui, é melhor evitar essa complicação específica.

Outra diferença da especificação oficial é que os identificadores do YouTube não usam o =caractere de preenchimento; não é necessário porque os comprimentos codificados esperados por tamanho inteiro decodificado respectivo são fixos e conhecidos (11 e 22 'dígitos' codificados para 64 e 128 bits, respectivamente).

Com uma exceção menor (discutida abaixo), os detalhes completos do mapeamento Base64 podem ser inferidos a partir de dados acessíveis ao público. Com um mínimo de adivinhação, é provável que a Base64 esquema usado nas videoId e channelId cordas é a seguinte:

    ——₀————₁————₂————₃————₄————₅————₆————₇————₈————₉———₁₀———₁₁———₁₂———₁₃———₁₄———₁₅—
     00ᴴ  01ᴴ  02ᴴ  03ᴴ  04ᴴ  05ᴴ  06ᴴ  07ᴴ  08ᴴ  09ᴴ  0Aᴴ  0Bᴴ  0Cᴴ  0Dᴴ  0Eᴴ  0Fᴴ
00→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      A    B    C    D    E    F    G    H    I    J    K    L    M    N    O    P

    —₁₆———₁₇———₁₈———₁₉———₂₀———₂₁———₂₂———₂₃———₂₄———₂₅———₂₆———₂₇———₂₈———₂₉———₃₀———₃₁—
     10ᴴ  11ᴴ  12ᴴ  13ᴴ  14ᴴ  15ᴴ  16ᴴ  17ᴴ  18ᴴ  19ᴴ  1Aᴴ  1Bᴴ  1Cᴴ  1Dᴴ  1Eᴴ  1Fᴴ
01→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      Q    R    S    T    U    V    W    X    Y    Z    a    b    c    d    e    f

    —₃₂———₃₃———₃₄———₃₅———₃₆———₃₇———₃₈———₃₉———₄₀———₄₁———₄₂———₄₃———₄₄———₄₅———₄₆———₄₇—
     20ᴴ  21ᴴ  22ᴴ  23ᴴ  24ᴴ  25ᴴ  26ᴴ  27ᴴ  28ᴴ  29ᴴ  2Aᴴ  2Bᴴ  2Cᴴ  2Dᴴ  2Eᴴ  2Fᴴ
10→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      g    h    i    j    k    l    m    n    o    p    q    r    s    t    u    v

    —₄₈———₄₉———₅₀———₅₁———₅₂———₅₃———₅₄———₅₅———₅₆———₅₇———₅₈———₅₉———₆₀———₆₁———₆₂———₆₃—
     30ᴴ  31ᴴ  32ᴴ  33ᴴ  34ᴴ  35ᴴ  36ᴴ  37ᴴ  38ᴴ  39ᴴ  3Aᴴ  3Bᴴ  3Cᴴ  3Dᴴ  3Eᴴ  3Fᴴ
11→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      w    x    y    z    0    1    2    3    4    5    6    7    8    9    -    _

A razão para acreditar que Base64 está sendo usado é que, quando assumimos tamanhos inteiros padrão de 64 e 128 bits para a entrada de encoder, Base64 prevê os comprimentos incomuns caracteres (11 e 22 caracteres) do YouTube channelId e videoId identificadores exatamente. Além disso, os restantes calculados de acordo com a Base64 explicam perfeitamente a variação distributiva observada encontrada no l̲a̲s̲t̲ c̲h̲a̲r̲a̲c̲t̲e̲r̲ de cada tipo de cadeia identificadora. A discussão desses pontos segue a seguir.

Nos dois casos, os "dados" binários que são codificados em Base64 são um único inteiro, de 64 ou 128 bits, para (respectivamente) videoId vs. channelId . Consequentemente, usando um decodificador Base64, um único número inteiro pode ser recuperado a partir do identificador de string, e pode ser bastante útil fazer isso porque, enquanto cada ID de número inteiro contém exatamente as mesmas informações que a string Base64 - e também permite que a string ser recriado a qualquer momento - quando comparada às seqüências Base64 armazenadas como Unicode, a representação binária é 63% menor, tem a densidade máxima de bits de 100%, alinha melhor a memória, classifica e hashes mais rapidamente e, talvez o mais importante, elimina colisões falsas entre identificadores que diferem apenas no caso ortográfico. Esse último problema, embora extremamente improvável numericamente, não pode ser descartado quando os IDs Base64 são tratados como não diferenciam maiúsculas de minúsculas, como fazem alguns sistemas de arquivos (por exemplo , Windows , que remonta ao DOS ).

Isso é meio importante: se você estiver usando um videoId / channelId string como parte de um nome de arquivo Windows / NTFS, há uma vanishingly miniscule- mas, no entanto diferente de zero -chance de colisões de nome de arquivo devido a esses sistemas de arquivos implantando caminho e nomes de arquivos case-insensitive .

Se você estiver preocupado com esse problema remotamente possível, uma maneira de eliminá-lo matematicamente seria recodificar os números inteiros decodificados - ainda obtidos conforme descrito neste artigo - em uma base 10 (decimal) ou (uniforme- caso) representação hexadecimal, para uso em nomes de caminho ou arquivo em tais sistemas de arquivos. [nota 2.] Nessa abordagem, o videoId de 64 bits precisaria de 20 dígitos decimais [0-9]ou 8 dígitos hexadecimais [0-9,A-F]( vs. 11 dígitos Base64). O channelId de 128 bits exigiria no máximo 39 dígitos decimais ou 16 dígitos hexadecimais ( vs. 22 dígitos Base64).

A decodificação para binário é trivial para o caso de 64 bits , porque você pode usar um UInt64( ulongem C # ) para armazenar o valor binário nativo que volta.

/// <summary> Recover the unique 64-bit value from an 11-character videoID </summary>
/// <remarks>
/// The method of padding shown here (i.e. 'b64pad') is provided to demonstrate the
/// full and correct padding requirement for Base64 in general. For our cases:
///
///    videoId    →  11 chars  →  b64pad[11 % 3]  →  b64pad[2]  →  "="
///    channelId  →  22-chars  →  b64pad[22 % 3]  →  b64pad[1]  →  "=="
///
/// Note however that, because it returns 'ulong', this function only works for videoId 
/// values, and the padding will always end up being "=". This is assumed in the revised
/// version of this code given further below, by just hard-coding the value "=".
/// </remarks>

static ulong YtEnc_to_videoId(String ytId)
{
    String b64 = ytId.Replace('-', '+').Replace('_', '/') + b64pad[ytId.Length % 3];

    return BitConverter.ToUInt64(Convert.FromBase64String(b64), 0);
}

static String[] b64pad = { "", "==", "=" };

No caso dos valores de 128 bits , é um pouco mais complicado, porque, a menos que seu compilador tenha uma __int128representação, você precisará descobrir uma maneira de armazenar a coisa toda e mantê-la combinada à medida que a distribuir . Um tipo de valor simples (ou System.Numerics.Vectors.Vector<T>que se manifesta como um registro de hardware SIMD de 128 bits, quando disponível) fará o truque no .NET (não mostrado).

[ edit: ]
Após uma reflexão mais aprofundada, uma parte do meu post original não estava no máximo completo. Para ser justo, o trecho original é mantido (você pode ignorá-lo, se desejar); imediatamente abaixo, explico o insight ausente:

[ original: ]
Você deve ter notado acima que eu escrevi que você pode recuperar " um " número inteiro. Este não seria o valor que foi originalmente codificado? Não necessariamente. E não estou aludindo à distinção assinada / não assinada que, é verdade, não pode ser verificada aqui (porque não altera nenhum fato sobre a imagem binária). São os próprios valores numéricos: sem alguns " Rosetta Stone"que nos permitiria verificar com valores absolutos conhecidos como" corretos ", o mapeamento numérico do alfabeto e também a endianidade não podem ser conhecidos positivamente, o que significa que não há garantia de que você esteja recuperando o mesmo valor que felizmente, desde que o YouTube nunca exponha publicamente os chamados valores corretos em um formato menos opaco em outro lugar, isso não pode importar.

Isso ocorre porque os valores decodificados de 64 ou 128 bits não têm nenhum uso, exceto como um token de identificação, de modo que nossos únicos requisitos para a transformação são codificação distinta (nenhum dois tokens exclusivos colidem) e reversibilidade (a decodificação recupera a identidade do token original).

Em outras palavras, tudo o que realmente importa é o disparo sem perdas da string Base64 original. Como o Base64 é sem perdas e reversível (desde que você mantenha sempre o mesmo mapeamento de alfabeto e suposição de endianidade para codificação e decodificação), ele satisfaz nossos propósitos. Seus valores numéricos podem não corresponder aos registrados no cofre principal do YouTube, mas você não poderá diferenciar.


[ Nova análise: ]
Acontece que lá são algumas pistas que podem nos contar sobre o "verdadeiro" Base64 mapeamento. Apenas certos mapeamentos preveem os caracteres de posição final que observamos, o que significa que o valor binário de apenas esses caracteres deve ter um certo número de zeros LSB. Heh.

Tomados em conjunto com a suposição provável de que os caracteres do alfabeto e do dígito são mapeados em ordem crescente, podemos basicamente confirmar que o mapeamento é o que é mostrado nas tabelas acima. A única incerteza restante sobre a qual a análise LSB é inconclusiva é a possível troca dos caracteres -e _( 62/ 63).

O texto original fez discutir essa questão LSB (ver mais abaixo), mas o que eu não realizar plenamente na época era como LSB informações age para restringir as possíveis Base64 mapeamentos.

Um último comentário sobre isso é que você pode escolher intencionalmente big-endian para a interpretação binária com a qual seu aplicativo trabalha internamente (mesmo que seja menos comum do que o little-endian atualmente e, portanto, não seja o que o YouTube 'oficialmente' faz) isto). O motivo é que este é um caso de visualizações duplas no mesmo valor, de forma que a ordem real de bytes seja visivelmente exposta na renderização Base64. É útil e menos confuso manter a ordem de classificação consistente entre o valor binário e a string Base64 legível por humanos (um pouco mais), mas o tipo dos valores binários little-endian é uma disputa não trivial da classificação ASCII / lexical desejada .

Não há uma solução simples para esse problema se você começar com valores de ID little-endian (ou seja, simplesmente reverter sua classificação não funcionará). Em vez disso, você deve planejar com antecedência e reverter os bytes de cada valor binário no momento da decodificação . Portanto, se você se preocupa com a exibição alfabética que corresponde à classificação dos valores binários, convém alterar a função mostrada acima para que ela decodifique em valores big-endian ulong . Aqui está esse código:

// Recover the unique 64-bit value (big-endian) from an 11-character videoID
static ulong YtEnc_to_videoId(String ytId)
{
    var a = Convert.FromBase64String(ytId.Replace('-', '+').Replace('_', '/') + "=");
    if (BitConverter.IsLittleEndian)   // true for most computers nowadays
        Array.Reverse(a); 
    return BitConverter.ToUInt64(a, 0);
}


IDs do YouTube


ID do vídeo

Para o videoId , é um número inteiro de 8 bytes (64 bits). A aplicação da codificação Base64 a 8 bytes de dados requer 11 caracteres . No entanto, como cada caractere Base64 transmite exatamente 6 bits (ou seja, 2⁶ é igual a 64), essa alocação pode realmente suportar até 11 × 6 = 66bits - um excedente de 2 bits nos 64 bits necessários para a carga útil. Os bits em excesso são definidos como zero, o que tem o efeito de excluir a exibição de certos caracteres na última posição da sequência codificada. Em particular, é garantido que o videoId termine sempre com um dos seguintes caracteres:

{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 }

Assim, a expressão regular com restrição máxima (RegEx) para o videoId seria a seguinte:

[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]


ID do canal ou da lista de reprodução

As cadeias channelId e playlistId são produzidas pela codificação Base64 de um número inteiro binário de 128 bits (16 bytes). Isso fornece uma cadeia de 22 caracteres que pode ser prefixada UCpara identificar o próprio canal ou UUpara identificar uma lista de reprodução completa dos vídeos que ele contém. Essas cadeias de caracteres com prefixo de 24 caracteres são usadas em URLs . Por exemplo, o seguinte mostra duas maneiras de se referir ao mesmo canal. Observe que a versão da lista de reprodução mostra o número total de vídeos no canal, [consulte a nota 3.], uma informação útil que as páginas do canal não expõem.

URL do canal
https://www.youtube.com/channel/UC K8sQmJBp8GCxrOtXWBpyEA
URL da lista de reprodução
https://www.youtube.com/playlist?list=UU K8sQmJBp8GCxrOtXWBpyEA

Como foi o caso do videoId de 11 caracteres , o cálculo por Base64 prediz corretamente o comprimento da string observado de 22 caracteres . Nesse caso, a saída é capaz de codificar 22 × 6 = 132bits, um excedente de 4 bits; esses zeros acabam restringindo m̲o̲s̲t̲ dos 64 símbolos do alfabeto na última posição, com apenas 4 restantes elegíveis. Portanto, sabemos que o último caractere em uma string channelId do YouTube deve ser um dos seguintes:

{ A, Q, g, w }

Isso nos dá a expressão regular com restrição máxima para um channelId :

[0-9A-Za-z_-]{21}[AQgw]

Como observação final, as expressões regulares mostradas acima descrevem apenas os valores de ID simples, sem os prefixos, barras, separadores, etc., que devem estar presentes nos URLs e nos outros usos diversos. Os padrões RegEx que apresentei são matematicamente mínimos possíveis, dadas as propriedades das sequências identificadoras, mas, se usadas como estão sem contexto adicional, provavelmente gerarão muitos falsos positivos, ou seja: correspondam incorretamente ao texto espúrio. Para evitar esse problema no uso real, envolva-os com o máximo possível do contexto adjacente esperado.


Notas

[1.]
Como prometido acima, aqui está um trecho da especificação Base64, que discute suas considerações ao selecionar os símbolos do alfabeto. Indivíduos que procuram entender como o processo foi concluído na seleção de caracteres com semântica de URL podem achar as explicações um tanto pouco redutoras.

3.4 Escolhendo o alfabeto

Aplicativos diferentes têm requisitos diferentes para os caracteres do alfabeto. Aqui estão alguns requisitos que determinam qual alfabeto deve ser usado:

  • Manipulado por seres humanos. Os caracteres "0" e "O" são facilmente confundidos, assim como "1", "l" e "I". No alfabeto base32 abaixo, onde 0 (zero) e 1 (um) não estão presentes, um decodificador pode interpretar 0 como O e 1 como I ou L, dependendo do caso. (No entanto, por padrão, não deve; consulte a seção anterior.)

  • Codificado em estruturas que exigem outros requisitos. Para as bases 16 e 32, isso determina o uso de letras maiúsculas ou minúsculas. Para a base 64, os caracteres não alfanuméricos (em particular, "/") podem ser problemáticos em nomes de arquivos e URLs.

  • Usado como identificadores. Certos caracteres, especialmente "+" e "/" no alfabeto base 64, são tratados como quebras de palavras pelas ferramentas de pesquisa / índice de texto herdadas.

Não existe um alfabeto universalmente aceito que atenda a todos os requisitos. Para um exemplo de uma variante altamente especializada, consulte IMAP [8]. Neste documento, documentamos e nomeamos alguns alfabetos usados ​​atualmente.

[2.]
Como alternativa, para resolver o problema do uso de cadeias de caracteres de ID codificadas em Base64 como componentes "como estão" dos nomes de arquivos ou caminhos no sistema de arquivos NTFS, que não diferencia maiúsculas de minúsculas por padrão (e, portanto, tecnicamente corre o risco de conflitar com um ou mais valores de ID não relacionados), acontece que o NTFS pode ser configurado com nomes de caminhos / arquivos que diferenciam maiúsculas de minúsculas por volume. A ativação do comportamento não padrão pode corrigir o problema descrito aqui, mas raramente é recomendado, pois altera as expectativas para todos os aplicativos diferentes que inspecionam ou acessam o volume. Se você está considerando essa opção, leia e entenda isso primeiro e provavelmente mudará de ideia.

[3.]
Acredito que o número total de vídeos mostrados na página da lista de reprodução do canal leve em consideração uma exclusão de vídeos restritos de acordo com a região geográfica do cliente HTTP. Isso explica qualquer discrepância entre o número de vídeos listados para a lista de reprodução versus o canal.

Glenn Slayden
fonte
3
Isso é um impressionante trabalho de detetive.
ale
3
Santo guacamole, estas respostas merece 1,000s de upvotes
pilau
Os IDs de canal do YouTube agora têm 24 caracteres, e não 22; por exemplo, UCjXfkj5iapKHJrhYfAF9ZGg; fonte: stackoverflow.com/questions/14366648/...
evandrix
1
@evandrix Obrigado pela sua observação. O último parágrafo da minha postagem foi feito para resolver esse problema; Eu apenas discuto a parte variável da cadeia de caracteres de identificação. Existem prefixos para o ID do canal (podem ser, por exemplo, UC ou UU ) que não são discutidos nesta publicação. Se você tiver um valor prefixado, como o seu exemplo, as informações fornecidas serão aplicadas aos últimos 22 caracteres.
Glenn Slayden
1
@evandrix Caso ainda esteja interessado, atualizei o artigo em si para incluir informações sobre os prefixos UC vs. UU channelId .
Glenn Slayden