Repository: streamlit/streamlit

Issue:
st.video() not working with a .mp4 file
# Summary

I have trouble running st.video() on videos that run fine with VLC.

## Details

I have a very simple app.py in the main of which I try to open a video : 
```python
def file_selector(folder_path='.'):
    filenames = os.listdir(folder_path)
    selected_filename = st.sidebar.selectbox('Select a video file', filenames)
    return os.path.join(folder_path, selected_filename)

filename = file_selector("media/footage")
if st.button("Play video"):
        video_file = open(filename, 'rb')
        video_bytes = video_file.read()
        st.video(video_bytes)
```

I generated the video twice, using a a list of numpy arrays, each one corresponding to a frame: 

Once by using the open cv VideoWriter function : 

```python
out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'{}'.format(codec)), fps, size)
for i in range(len(img_array)):
        out.write(img_array[i])
        out.release()
```

This produces a file which I can select, and which I can also play in VLC mediaplayer but for which streamlit says : 

**'No video with supported format and MIME type found'**

Then I tried changing the video generation method to skvideo.io VideoWriter by using the following: 

```python
writer = skvideo.io.FFmpegWriter(output_directory + "skvideo_writer_49.mp4")
for i in range(len(img_array)):
    writer.writeFrame(img_array[i])
writer.close()
```

And now the video is perfectly playable on VLC mediaplayer however on the app, I get : 

**'Video can't be played because the file is corrupt'**

## Reproduce bug

I am running the streamlit app on a distant machine to which I am connected on my work's Vpn and forwarding the app onto a port on my laptop.

However I have determined that this is not the cause of the problem by reproducing this error on my local machine with the following : 

You just need a folder : 

-the_streamlit_app.py
-media
--footage
---the_video.mp4 

with this code : 
```python
import os
import streamlit as st

def file_selector(folder_path='.'):
    filenames = os.listdir(folder_path)
    selected_filename = st.sidebar.selectbox('Select a video file', filenames)
    return os.path.join(folder_path, selected_filename)

def main():
    filename = file_selector("media/footage")
    if st.button("Play video"):
        video_file = open(filename, 'rb')
        video_bytes = video_file.read()
        st.video(video_bytes)

if __name__ == '__main__':
    main()
```

EDIT : In order to make it more easily reproducible, I have hosted the file that does not work here https://drive.google.com/file/d/1rIyU0__Q4uwpKCVZLMF-nErA3a68IJM0/view?usp=sharing

## Expected behavior:

I expect the streamlit app to be displaying the video correctly

## Actual behavior:

Each time I try to play the video, I get an error message

## Is this a regression?

This is the first time I have used this feature

# Debug info

- Streamlit version: Streamlit, version 0.59.0
- Python version: Python 3.8.2
- Using: Conda 4.8.2
- OS version: 'NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.3 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
' (same OS my laptop and the distant machine)
- Browser version: Firefox 77.0.1




Discussion:
I fixed the bug ! 
It comes from the fact that streamlit video uses the HTML5 video player that does not support the default mp4 codecs of openCV and skvideo.

The workaround I have found is to use the H264 codec which is supported by the HTML5 video player, and to convert my existing mp4 video into that codec using ffmpeg.

## Solution : 

```
fmpeg -i input_video_created_by_OpenCV.mp4 -vcodec libx264 output_video_that_streamlit_can_play.mp4
```
Hi @Hadrien-Cornier, glad you figured it out!

I'm going to leave this open and tag it as a docs issue...even though it's not a Streamlit issue per se, it's happening frequently enough where we should make a note about it.

Resolving patch:
diff --git a/lib/streamlit/DeltaGenerator.py b/lib/streamlit/DeltaGenerator.py
--- a/lib/streamlit/DeltaGenerator.py
+++ b/lib/streamlit/DeltaGenerator.py
@@ -1593,6 +1593,13 @@ def video(self, element, data, format="video/mp4", start_time=0):
            https://share.streamlit.io/0.25.0-2JkNY/index.html?id=Wba9sZELKfKwXH4nDCCbMv
            height: 600px
 
+        .. note::
+           Some videos may not display if they are encoded using MP4V (which is an export option in OpenCV), as this codec is
+           not widely supported by browsers. Converting your video to H.264 will allow the video to be displayed in Streamlit.
+           See this `StackOverflow post <https://stackoverflow.com/a/49535220/2394542>`_ or this
+           `Streamlit forum post <https://discuss.streamlit.io/t/st-video-doesnt-show-opencv-generated-mp4/3193/2>`_
+           for more information.
+
         """
         from .elements import media_proto
 


Test patch: