Skip to content
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 demos/video-capture-simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ def main() -> None:
with mss.mss() as sct:
monitor = sct.monitors[1]

# Because of how H.264 video stores color information, libx264 requires the video size to be a multiple of
# two.
monitor["width"] = (monitor["width"] // 2) * 2
monitor["height"] = (monitor["height"] // 2) * 2

with av.open(FILENAME, "w") as avmux:
# The "avmux" object we get back from "av.open" represents the MP4 file. That's a container that holds
# the video, as well as possibly audio and more. These are each called "streams". We only create one
Expand Down
18 changes: 18 additions & 0 deletions demos/video-capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,12 @@ def main() -> None:
metavar="LEFT,TOP,RIGHT,BOTTOM",
help="region to capture as comma-separated coordinates",
)
parser.add_argument(
"-2",
"--region-crop-to-multiple-of-two",
action=argparse.BooleanOptionalAction,
help="crop the capture region to a multiple of two, as required by some codecs (default: only for libx264 and libx265)",
)
parser.add_argument(
"-c",
"--codec",
Expand Down Expand Up @@ -426,6 +432,7 @@ def main() -> None:
codec = args.codec
filename = args.output
duration_secs = args.duration_secs
region_crop_to_multiple_of_two = args.region_crop_to_multiple_of_two

with mss.mss() as sct:
if args.region:
Expand All @@ -439,6 +446,17 @@ def main() -> None:
else:
monitor = sct.monitors[args.monitor]

# Some codecs, such as libx264, require the region to be a multiple of 2, to get the chroma subsampling right.
# Others, such as h264_nvenc, do not; they'll pad to get the subsampling region, and add flags to the stream
# to tell the viewer to crop accordingly.
if region_crop_to_multiple_of_two is None:
# The user didn't specify; choose the default. We haven't tested many codecs, but we know these require
# it (at least, when using 4:2:0 subsampling).
region_crop_to_multiple_of_two = codec in {"libx264", "libx265"}
if region_crop_to_multiple_of_two:
monitor["width"] = (monitor["width"] // 2) * 2
monitor["height"] = (monitor["height"] // 2) * 2

# We don't pass the container format to av.open here, so it will choose it based on the extension: .mp4, .mkv,
# etc.
with av.open(filename, "w") as avmux:
Expand Down