Encoding VR 360 and 180 immersive videos for Oculus Media Studio and sideloading into Oculus Quest and Go
ArticlesMost immersive video content made for VR is encoded either for local (“sideloaded”) playback, or for uploading to VR video streaming platforms like Oculus Media Studio and YouTube VR.
There is an article on the Oculus blog that discusses how to encode high-resolution 360 and 180 videos for playback in Oculus Quest and Go (disclosure: I wrote it). However, if you’re encoding immersive video to upload to Oculus Media Studio, you’ll want to target your encodes to match the specs for Oculus Media Studio.
Here are the settings I use for encoding for Oculus Media Studio, for sideloading, and for full-resolution playback when I have a computer handy (using Quest and Oculus Link).
These encodes favor quality over small file size. If you’re trying to get your file sizes small, increase crf values accordingly (there will be a tradeoff in image quality).
3D-360
(assumes over/under content)
oculus media studio
ffmpeg -i "input.mov" -c:v libx264 -preset slow -crf 15 -vf "scale=3840x3840" -pix_fmt yuv420p -g 15 -an -movflags faststart "output_mediastudio_3840_crf15_g15.mp4"
sideload h265 (Quest and Go), very high quality
ffmpeg -i "input.mov" -c:v libx265 -preset slow -crf 17 -vf "scale=4096x4096" -pix_fmt yuv420p -an -movflags faststart "output_sideload_4096_h265_crf17.mp4"
sideload h264 (safe), very high quality
ffmpeg -i "input.mov" -c:v libx264 -preset slow -crf 17 -x264-params mvrange=511 -vf "scale=3840x3840" -pix_fmt yuv420p -an -movflags faststart "output_3840_h264_crf17_sideload.mp4"
full res h264 (computer playback), very high quality
ffmpeg -i "input.mov" -c:v libx264 -preset slow -crf 17 -pix_fmt yuv420p -an -movflags faststart "output_fullres_crf17.mp4"
Cropped to 3D-180 (scaled, high-res center crop from over/under 3D-360 source)
ffmpeg -i "input.mov" -c:v libx265 -preset slow -crf 17 -filter_complex "crop=iw/2:ih:iw/4:0, scale=2880x5760" -pix_fmt yuv420p -aspect 1:2 -an -movflags faststart "output_3D180_TB_h265_crf17.mp4"
Cropped to 3D-180 and transposed to side-by-side:
ffmpeg -i "input.mov" -c:v libx265 -preset slow -crf 17 -filter_complex "crop=iw/2:ih:iw/4:0, scale=2880x5760, stereo3d=abl:sbs2l" -pix_fmt yuv420p -aspect 1:2 -an -movflags faststart "output_3D180_SBS_h265_crf17.mp4"
60fps
For 60fps, 3D-360 content, scale to 3072×3840 or 2880×2880 (for h.264 only; max h.265 playback resolution unverified)
3D-180 (VR180)
(assumes side-by-side source content)
oculus media studio, source >= 5760×2880
ffmpeg -i "input.mov" -c:v libx264 -preset slow -crf 15 -vf "scale=5760x2880" -pix_fmt yuv420p -g 15 -an -movflags faststart "output_mediastudio_5760_crf15_g15.mp4"
If source < 5760×2880, remove ‘-vf “scale=5760×2880″‘.
sideload h265 (Quest and Go), very high quality
ffmpeg -y -i "input.mov" -c:v libx265 -preset veryslow -crf 17 -vf "stereo3d=sbs2l:abl, scale=2880x5760" -pix_fmt yuv420p -aspect 1:2 -an -movflags faststart "output_sideload_5760_h265_crf17.mp4"
If source < 5760×2880 , change ‘scale=2880×5760’ to match transposed source resolution (e.g., ‘scale=2560×5120’ for 5120×2560 source).
sideload h264 (safe), very high quality
ffmpeg -i "input.mov" -c:v libx264 -preset slow -crf 17 -x264-params mvrange=511 -vf "scale=5760x2880" -pix_fmt yuv420p -an -movflags faststart "output_5760_h264_crf17_sideload.mp4"
If source < 5760×2880, remove ‘-vf “scale=5760×2880″‘.
full res h264 (computer playback), very high quality
ffmpeg -i "input.mov" -c:v libx264 -preset slow -crf 17 -pix_fmt yuv420p -an -movflags faststart "output_fullres_crf17.mp4"
For 60fps 3D-180 content, scale to 4400×2200 for h.264, and 4096×2048 for h.265. Alternatively, you might try VP9 encoding and playback (below)…
sideload 60fps (max resolution VP9 encode)
ffmpeg -i "input.mov" -vf scale=4700x2350 -b:v 0 -auto-alt-ref 1 -lag-in-frames 19 -threads 16 -quality good -crf 34 -g 300 -c:v libvpx-vp9 -pass 1 -passlogfile "passlog" -speed 3 -aspect 2:1 -pix_fmt yuv420p -an -y -f mp4 NUL && ffmpeg -i "input.mov" -vf scale=4700x2350 -b:v 0 -auto-alt-ref 1 -lag-in-frames 19 -threads 16 -quality good -crf 34 -g 300 -c:v libvpx-vp9 -pass 2 -passlogfile "passlog" -speed 1 -aspect 2:1 -pix_fmt yuv420p -c:a aac -b:a 160k -y "output_4700_60_vp9_crf34.mkv"
This is a two-step encode and includes two commands on one line formatted for Windows. If you are on Linux/Mac, replace “NUL” with “/dev/null”.
Audio
These encodes all encode video only, throwing away the audio track. To copy or encode a stereo audio track from your input video:
- Copy audio: replace ‘-an’ with ‘-c:a copy’
- Encode audio as aac: replace ‘-an’ with ‘-c:a aac -b:a 160k’
Metadata
Finally, to inject the correct metadata for uploading to Oculus Media Studio, install Facebook Spatial Workstation and use FB360 Encoder to encode and mux your spatial audio. Choose “Facebook 360” or “Facebook 180”, and the matching stereoscopic arrangement, if relevant. The encoder will tag your final distribution file with the proper metadata for both video and audio.
If you’re targeting Youtube VR, you’ll want to use Spatial Media Injector and/or the VR180 Creator tool.
If you have an Oculus Quest or Go, check out some of my content in Oculus Media Studio. Click “Save to VR” and put on your headset…
That’s it–happy creating!