Skip to content
This repository has been archived by the owner on Aug 10, 2022. It is now read-only.

Draft of file manipulation article. #4682

Merged
merged 19 commits into from Jun 29, 2017
Merged

Draft of file manipulation article. #4682

merged 19 commits into from Jun 29, 2017

Conversation

jpmedley
Copy link
Contributor

I don't know why this PR is showing changes to the cheatsheet. Those have already been merged to master.

@@ -191,11 +194,6 @@ remove all whitespace including the final carriage return.
For the `-key` flag use the key created earlier and stored in the media.key
file. However, when entering it on the command line, be sure you've removed its
whitespace. For the `-key_id` flag repeat the key value.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

key_id is really an identifier that uniquely identifies the key. It can usually be found in the manifests and media containers in plain text/hex.

Some applications concatenate key_id and key and store them together, e.g. Apple's segmenter tool. This gives an impression that key_id is part of the key, but it is actually not.

The size of key needs to be 16 bytes because we are using AES-128 (128 bits, 16 bytes) for CENC and SAMPLE-AES.

The requirement of key-id being 16 bytes comes from CENC spec (23001-7) which requires key-id (KID) to be 16 bytes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"It can usually be found in the manifests and media containers in plain text/hex." What manifests and media containers?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I thought you meant. But I haven't created the MPD yet. Is there some place else I can get it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can find it in CENC spec (23001-7:2016).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full text of the spec in $118. Can you please just give me the answer?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what answer you need. I think you can just say:

key_id is an identifier that uniquely identifies the key.

If you want, you can mention that:

It is available in packager outputs in plaintext. It will be used by the player / content decryption module to select the right key to decrypt the content.

Let me know if you need anything else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if I'm encrypting in but not doing DASH? Is there some other way to get the key_id?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned earlier, it is also available in tenc box for fMP4.

> **Note:** Technically, the key ID is supposed to be either the first 8 OR the
> first 16 hex digits of the key. Since packager requires the key to be 16
> digits and does not allow a 32 digit key, both flags use the same value.


packager \
input=myvideo.mp4,stream=audio,output=glocka.m4a \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--enable_fixed_key_decryption is not needed below.

'-key_id INSERT_KEY_HERE' should be '-key_id INSERT_KEY_ID_HERE'

--enable_widevine_encryption \
--key_server_url "https://license.uat.widevine.com/cenc/getcontentkey/widevine_test" \
--content_id "fd385d9f9a14bb09" --signer "widevine_test" \
--content_id "16_Rand_Hex_Chrs" --signer "widevine_test" \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'content_id' is an unique identifier identifies the content. There is no restriction on the size of content id. In fact, you can use an arbitrary size string as content_id. It does need to be hex converted before supplying it to packager.

It does not need to be randomly generated either.

Before I start manipulating media files, I want to talk a bit about how media
files are put together. I think of them as being like an onion. The file that
you see in your operating system shell is a _container_, identified by a file
extension (mp4, webm, etc.). The container houses from one to four _streams_,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some containers allows multiple streams of the same type, e.g. webm

ffmpeg -i myvideo.webm -vcodec copy -an myvideo_video.webm
ffmpeg -i myvideo.webm -acodec copy -vn myvideo_audio.webm

Just as with Shaka Packer, we have both an input and an output file. Another
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Packer/Packager/

the top three. If you're serving video someplace like India, you'll want to
include 2G as well. For demonstration purposes, I'm going to target 3G.

In Shaka Packager you set the bitrate by adding the bandwidth option to the
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bandwidth option in Shaka Packager does not modify the bit rate of the content. It is used to finetune the bandwidth value appears in the manifests (DASH MPDs or HLS playlists). If not provided, packager will estimate from the content.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what packager --help says:

"bandwidth (bw): Optional value which contains a user-specified
content bit rate for the stream, in bits/sec."

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the misleading description. I will fix the description in Shaka packager to make it clearer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then how do I set the bit rate using Packager?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packager does not do transcoding, so there is no way to set/modify the bit rate. Normally the user prepares multi-bitrate streams, e.g. using FFmpeg or another encoder, then feed the multi-bitrate streams to packager.

@jpmedley
Copy link
Contributor Author

@kqyang Thanks for the feedback. I have questions about 2 of the comments. I've made changes for the others.

+ Audio and video streams are split into separate files
+ Versions of the video file are in mp4 and webm format
+ Versions of the audio file are in m4a and webm format
+ A bitrate of 0.35 Megabits per seconde (Mbs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seconde -> second

files are put together. I think of them as being like an onion. The file that
you see in your operating system shell is a _container_, identified by a file
extension (mp4, webm, etc.). The container houses one or more _streams_ of up to
four types, specifically audio, video, captions, and data. Although containers

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are definitely more than four types of streams, and some media files can have 30, 40 or more streams. Sorry I missed this in 'Application Primers' earlier.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You appear to be using 'streams' and 'types of streams' interchangeably. I'm not. Can you please clarify?

Let's start by changing the file container. You'll recall that we're starting
with a file that has an mov extension. I'm going to use ffmpeg to change the
container type from mov to mp4 and webm. In actual practice, you would likely
specify a codec at the same time. For this lesson, I'm letting ffmpeg use it's

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's -> its

When you package media resources, for HLS and DASH, you'll need to separate the
video and audio streams. Splitting the audio and video streams of a file is
often referred to as **demultiplexing** or **demuxing** for short. Professional
content creators record audio and video to separate files to begin with. If

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

creators often record audio and video to separate files

Plenty of high-end devices create single files with both audio and video


## File properties

I've unpealed the onion. Yet if you compare what I've done to the list of stated

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unpealed -> unpeeled

goals you'll see that I'm not quite done. Anong the remaining items are bitrate
and resolution. These properties correlate to the amount of data in a media
file. It probably goes without saying, but I'm going to say it anyway, that you
can always lower bitrate and resolution, but you can't increase them. (Well,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can increase both (e.g. SD to HD) and there are algorithms to help with quality. Remove that bit please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reworded it a bit. See what you think.

recommends](https://support.google.com/youtube/answer/6375112) the following
resolutions for video uploads, all in the 16:9 aspect ratio. There's nothing
specific to Youtube about this list, which makes it a good guide for video on
the web in general.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all pretty standard 16:9 resolutions for video; I'd take out "which makes it a good guide..." and replace with "it's just a list of common 16:9 video resolutions."

| 360p | 640x360 |
| 240p | 426x240 |

Which one do I use? Again, the short answer is all of them. Fortunately, this is

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just make this functional: "You might use one or all of these depending upon your application. Fortunately, this is one of the simplest..."

Unless your company completes the Master License Agreement with
[Widevine]([http://www.widevine.com/contact.html](http://www.widevine.com/contact.html))
, this type of encryption can really only be used for testing. Since this is
covered without much explanation on the Shaka Packager READMEhere it goes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

READMEhere -> README, here


This does not cover everything you could do to a media file before posting it to
the web, not by a longshot. To be fair, this subject is one deserving of a
website that is itself as large as [developers.google.com/web/](/web/). I'm

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd take out this section; we're trying to create this sub-site for posting to the web here. Could reference developers.google.com/media/vp9 for VP9/WebM encoding if you'd like.

the top three. If you're serving video someplace like India, you'll want to
include 2G as well. For demonstration purposes, I'm going to target 3G.

In Shaka Packager you set the bitrate by adding the bandwidth option to the
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the misleading description. I will fix the description in Shaka packager to make it clearer.

@@ -233,7 +233,7 @@ This command will accept a key with either 16 or 32 characters.
input=glocken.mp4,stream=audio,output=enc_audio.m4a \
--enable_widevine_encryption \
--key_server_url "https://license.uat.widevine.com/cenc/getcontentkey/widevine_test" \
--content_id "16_Rand_Hex_Chrs" --signer "widevine_test" \
--content_id "Hec_converted_random_ID" --signer "widevine_test" \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Hec/Hex/

I'd also replace random with unique.

@paullewis paullewis removed their assignment Jun 22, 2017
@jpmedley
Copy link
Contributor Author

@beaufortfrancois I didn't realize you were taking over from Sam. Can you please review this in the next few days?

| Desktop web video | 2 Mbs |
| 4G mobile video | 0.7 Mbs |
| 3G mobile video | 0.35 Mbs |
| 2G mobile video | ?? |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"??"?

{# wf_updated_on: 2017-06-23 #}
{# wf_published_on: 2017-06-23 #}

# Media File Manipulation {: .page-title }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this probably isn't "Media File Manipulation" - it's "Transforming a raw video file into an encrypted multi-bandwidth resource" or the like?

To be more specific about the goals, the result of the procedures described here
will be media resources with the following characteristics:

+ Audio and video streams are split into separate files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you splitting into separate files? Is this/why is this a good idea?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See line 106. I said it's done that way for HLS and DASH. I guess I should have asked if HLS and DASH required this. (I thought it did, but maybe it doesn't.) Even if it doesn't, it would seem to me to be more efficient if the dynamic part of DASH only had to deal with one type of stream at a time.

Maybe @johnpallett or @beaufortfrancois could comment on this.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a requirement in DASH.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add that comment here, since it's 75 more lines before you get there - just a "(this is required by DASH)".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably just seems that way because this is where you thought of the question. This intro list contains a lot that's justified later, specifically the bitrate and resolution. If I start explaining all this stuff here, the introduction will bloat and start to lose its effectiveness.


Notice that the stream descriptor has an input, an output, and a stream type.
You might remember from [Application Primers](applications) that Shaka Packager
can take multiple stream descriptors. This means that Shaka Packager lets me
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the final product is a single

may chose one, several, or all. Fortunately, this is one of the simplest
transformations you'll make with ffmpeg.

ffmpeg -i myvideo.webm -s 1920x1080 myvideo_1980x1020.webm
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be myvideo_1920x1080.webm?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed both.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still seeing 1980x1020.webm instead of 1920x1080.webm.

@@ -2,7 +2,7 @@ project_path: /web/_project.yaml
book_path: /web/fundamentals/_book.yaml
description: A summary of commands used to convert a raw mov file to an encrypted full HD file for web playback.

{# wf_updated_on: 2017-06-12 #}
{# wf_updated_on: 2017-06-23 #}
{# wf_published_on: 2017-06-09 #}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think '(1920 x 1980)should be(1920 x 1080)`.

@jpmedley
Copy link
Contributor Author

@cwilso Can you please approve the changes today or tomorrow?

Copy link
Member

@beaufortfrancois beaufortfrancois left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @jpmedley for writing this. I've learnt a lot ;)
See my nits.

@@ -0,0 +1,331 @@
project_path: /web/_project.yaml
book_path: /web/fundamentals/_book.yaml
description: TBD.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add description


Within the audio and video streams, the actual data is compressed using a
_codec_. As we'll see later, the distinction between a container and a codec is
import as files with the same container can have their contents encoded with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/import/important

ffmpeg -i glocken.mov -vf setsar=1:1 glocken.webm

Webm takes quite a bit longer to create than mp4. This isn't surprising when
you look at the results. While mp4 compresses to about a quarter of the original
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to mention which version of ffmpeg you used.

you look at the results. While mp4 compresses to about a quarter of the original
file's size, webm compresses to 1% of the original file's size.

-rw-r--r-- 1 jmedley eng 12080306 May 9 14:34 glocken.mov
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the kind of output I'd use:

ls glocken.* -hlGrt
-rw-r--r--. 1 fr  12M Jun 27 11:48 glocken.mov
-rw-rw-r--. 1 fr 9.7M Jun 27 14:47 glocken.mp4
-rw-rw-r--. 1 fr 480K Jun 27 14:50 glocken.webm

This makes it easier to read.


Webm takes quite a bit longer to create than mp4. This isn't surprising when
you look at the results. While mp4 compresses to about a quarter of the original
file's size, webm compresses to 1% of the original file's size.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get 4% for webm, and 83% for mp4.

## File properties

I've unpeeled the onion. Yet if you compare what I've done to the list of stated
goals you'll see that I'm not quite done. Anong the remaining items are bitrate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Anong/Among


ffmpeg -i glocken.mov -b:v 350K -b:a 350K glocken.mp4

Notice that there are two bitrate flags, -b:a and -b:v. One is for audio and the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add backquotes for -b:a and -b:v

This example implies that I've typed or pasted the key into the command line
manually. There's no reason you can't get fancy.

packager \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work for me as the media.key file contains characters that can't be displayed in the terminal. How did you get it to work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me dig into this some more.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be hex encoded.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not central to the article, so I'm taking it out.

input=myvideo.mp4,stream=video,output=glockv.mp4 \
--enable_fixed_key_encryption --enable_fixed_key_decryption \
-key "$(< media.key)" -key_id "$(< media.key)"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to add a way for user to check that the file is indeed encrypted with:

packager input=glocken_video_encrypted.mp4  --dump_stream_info

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, since this is useful for every step in the process, I've added a short section called "Check your work" at the beginning of the article.

digits and does not allow a 32 digit key, both flags use the same value.

packager \
input=myvideo.mp4,stream=audio,output=glocka.m4a \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

output=glocken_video_encrypted.mp4 and output=glocken_audio_encrypted.m4a makes it easier to read.

@beaufortfrancois
Copy link
Member

@jpmedley Please resolve conflicts so that https://pr-4682-dot-web-central.appspot.com/web/fundamentals/media/manipulating/files is updated accordingly to your latest changes.

To be more specific about the goals, the result of the procedures described here
will be media resources with the following characteristics:

+ Audio and video streams are split into separate files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add that comment here, since it's 75 more lines before you get there - just a "(this is required by DASH)".


This does not cover everything you could do to a media file before posting it to
the web, not by a longshot. To be fair, this subject is one deserving of its own
website. I'm hoping this introduction will give you enough to help you find your
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would cut the "To be fair..." sentence, and let's keep this on the list to expand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving in. I want to be open and honest about the limits of what I've done.

@jpmedley
Copy link
Contributor Author

@cwilso Conversation view is showing my response to your second comment, but not your first. Please click over to Files Changed to see it.

@cwilso
Copy link
Contributor

cwilso commented Jun 29, 2017

ok.

@beaufortfrancois
Copy link
Member

LGTM @jpmedley
Thank you!

@jpmedley jpmedley merged commit 689ff84 into master Jun 29, 2017
@jpmedley jpmedley deleted the manipulation branch June 29, 2017 19:57
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants