Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add w3c common-pssh-box uuid + make uuid check case-insensitive #318

Merged
merged 1 commit into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Support avc3 sample description when encrypting
- Full ProfileLevelTier parsing for HEVC
- Make pssh UUID comparison case-insensitive

### Added

- W3C Common PSSH Box UUID

## [0.41.0] - 2024-01-12

Expand Down
23 changes: 16 additions & 7 deletions mp4/pssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ import (
"encoding/hex"
"fmt"
"io"
"strings"

"github.com/Eyevinn/mp4ff/bits"
)

// UUIDs for different DRM systems
const (
UUIDPlayReady = "9a04f079-9840-4286-ab92-e65be0885f95"
UUIDWidevine = "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
UUIDFairPlay = "94CE86FB-07FF-4F43-ADB8-93D2FA968CA2"
UUID_VCAS = "9a27dd82-fde2-4725-8cbc-4234aa06ec09"
UUIDPlayReady = "9a04f079-9840-4286-ab92-e65be0885f95"
UUIDWidevine = "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
UUIDFairPlay = "94ce86fb-07ff-4f43-adb8-93d2fa968ca2"
UUID_VCAS = "9a27dd82-fde2-4725-8cbc-4234aa06ec09"
UUID_W3C_COMMON = "1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"
)

// UUID - 16-byte KeyID or SystemID
Expand All @@ -28,8 +30,11 @@ func (u UUID) String() string {
return fmt.Sprintf("%s-%s-%s-%s-%s", h[0:8], h[8:12], h[12:16], h[16:20], h[20:32])
}

// NewUUIDFromHex creates a UUID from a hexadecimal string with 32 chars
// NewUUIDFromHex creates a UUID from a hexadecimal string with 32 chars or 36 chars (with dashes)
func NewUUIDFromHex(h string) (UUID, error) {
if len(h) == 36 {
h = strings.ReplaceAll(h, "-", "")
}
if len(h) != 32 {
return nil, fmt.Errorf("hex has %d chars, not 32", len(h))
}
Expand All @@ -40,8 +45,10 @@ func NewUUIDFromHex(h string) (UUID, error) {
return UUID(s), nil
}

func systemName(systemID UUID) string {
// ProtectionSystemName returns name of protection system if known.
func ProtectionSystemName(systemID UUID) string {
uStr := systemID.String()
uStr = strings.ToLower(uStr)
switch uStr {
case UUIDPlayReady:
return "PlayReady"
Expand All @@ -51,6 +58,8 @@ func systemName(systemID UUID) string {
return "FairPlay"
case UUID_VCAS:
return "Verimatrix VCAS"
case UUID_W3C_COMMON:
return "W3C Common PSSH box"
default:
return "Unknown"
}
Expand Down Expand Up @@ -146,7 +155,7 @@ func (b *PsshBox) EncodeSW(sw bits.SliceWriter) error {
// Info - write box info to w
func (b *PsshBox) Info(w io.Writer, specificBoxLevels, indent, indentStep string) (err error) {
bd := newInfoDumper(w, indent, b, int(b.Version), b.Flags)
bd.write(" - systemID: %s (%s)", b.SystemID, systemName(b.SystemID))
bd.write(" - systemID: %s (%s)", b.SystemID, ProtectionSystemName(b.SystemID))
if b.Version > 0 {
for i, kid := range b.KIDs {
bd.write(" - KID[%d]=%s", i+1, kid)
Expand Down
23 changes: 23 additions & 0 deletions mp4/pssh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,28 @@ func TestEncodeDecodePSSH(t *testing.T) {
Data: []byte("some data"),
}
boxDiffAfterEncodeAndDecode(t, pssh)
}

func TestPsshUUIDs(t *testing.T) {
cases := []struct {
hexUUIDs string
expectedName string
}{
{"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed", "Widevine"},
{"9a04f079-9840-4286-ab92-e65be0885f95", "PlayReady"},
{"94CE86FB-07FF-4F43-ADB8-93D2FA968CA2", "FairPlay"},
{"9a27dd82-fde2-4725-8cbc-4234aa06ec09", "Verimatrix VCAS"},
{"1077efec-c0b2-4d02-ace3-3c1e52e2fb4b", "W3C Common PSSH box"},
{"00000000-0000-0000-0000-000000000000", "Unknown"},
}

for _, c := range cases {
u, err := NewUUIDFromHex(c.hexUUIDs)
if err != nil {
t.Fatal(err)
}
if ProtectionSystemName(u) != c.expectedName {
t.Errorf("Expected %s, got %s", c.expectedName, ProtectionSystemName(u))
}
}
}
Loading