Is this an appropriate use of abstract classes and inheritance?
Is this a decent use of abstract classes and inheritance?


Yes, it's decent. My personal preference is, rather than using ABC, simply

def process(self):
    # Method to process frames.
    # Method will be overwritten by subclasses
    raise NotImplementedError()


You can also simplify this somewhat by


Renaming Video to ColorVideo
Deleting the class that is now called ColorVideo
Rather than making process abstract, make it "virtual" (in C++ parlance): make it take the contents of what is now get_raw_frame and delete get_raw_frame
In the child GrayVideo, override process to call its super().process and convert the results


If you're concerned that this more minimal representation is confusing (i.e. why is a GrayVideo a ColorVideo?) then you can keep Video as a conceptually abstract class, and simply

class ColorVideo(Video):
    pass


Other stuff:


end should actually be the __exit__ of a context manager; 
it looks like your source argument should take a default of 0;
make a main function called by standard __name__ guard.