首页 > 解决方案 > 如何修复画廊中的视频不播放(可能是来自 ffmpeg 的编码)

问题描述

我正在设置一个视频流,通过它我可以将视频下载到 Android 库中,以便稍后播放。我在从图库播放视频时遇到问题。尝试在 videoview 中查看 url 时会出现同样的问题。

来自 ffmpeg 的视频信息显示了这一点。

Input #0, mpjpeg, from '':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[swscaler @ 0x1cab5e0] deprecated pixel format used, make sure you did set range correctly
[libx264 @ 0x1c6f030] using cpu capabilities: ARMv6 NEON
[libx264 @ 0x1c6f030] profile Constrained Baseline, level 3.0, 4:2:0, 8-bit
[libx264 @ 0x1c6f030] 264 - core 157 r2969 d4099dd - H.264/MPEG-4 AVC codec - Copyleft 2003-2019 - http://www.videolan.org/x264.html - options: cabac=0 ref=2 deblock=1:0:0 analyse=0x1:0x111 me=hex subme=6 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=30 rc=crf mbtree=1 crf=18.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'out.mp4':
  Metadata:
    encoder         : Lavf58.33.100
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 720x406, q=-1--1, 30 fps, 15360 tbn, 30 tbc
    Metadata:
      encoder         : Lavc58.59.101 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
Error opening file out.mp4: IsoMedia File is truncated28.56 bitrate= 734.1kbits/s speed=0.478x
[pid: 5138|app: 0|req: 1/1] 192.168.178.21 () {32 vars in 406 bytes} [Mon Oct  7 01:12:17 2019] GET /stop => generated 39 bytes in 152 msecs (HTTP/1.1 200) 2 headers in 79 bytes (1 switches on core 0)
frame=  899 fps= 15 q=-1.0 Lsize=    2779kB time=00:00:29.93 bitrate= 760.6kbits/s speed=0.49x
video:2775kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.157041%

我试图关注这篇文章。Android MediaPlayer 错误 (1, -2147483648)

我正在使用 FFMpeg 将 mjpeg 流录制到文件中,然后由 uwsgi/flask 服务器托管到一个方便的 url:http://ipaddress/video.mp4

到目前为止,我能够在 Android 中使用 chrome 打开视频。

我的 FFMPEG 命令如下所示:

ffmpeg -i $1 -crf 18 -r 30 -vf "scale=720x406, setpts='1/(30*TB) * (N + 0.05 * sin(N*2*PI/25))', fps=fps=30" -profile:v baseline -pix_fmt yuv420p -f mp4 -preset fast out.mp4

我认为这可能与文件的传输有关。我正在使用一个名为 volley 的 android 库来发送 url,以便可以将其作为文件下载到 Android 上。然后它随后被放入画廊。这是我开始遇到问题的时候。我想彻底,所以试图找出文件内容是否是问题所在。这是因为在画廊中显示它时,没有宽度或高度信息,甚至没有持续时间。我开始怀疑ffmpeg有问题。如果找不到正常的文件属性,我并没有删除它可能会阻止文件打开。

下载文件的 volley 代码如下:

 @Override
    public void onResponse(byte[] response) {
        try {
            if (response!=null) {

                File file = createVideoFile();

                FileOutputStream stream = new FileOutputStream(file);
                try {
                    stream.write(response);
                } finally {
                    stream.close();
                }

                addToGallery(file.getAbsolutePath());
                MediaScannerConnection.scanFile(this, new String[]{file.getAbsolutePath()}, null, (path, uri) -> {
                    Intent intent = new Intent (context, VideoActivity.class);
                    intent.setData(uri);
                    startActivity(intent);

                });


                Toast.makeText(this, "Download complete.", Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Log.d("KEY_ERROR", "UNABLE TO DOWNLOAD FILE");
            e.printStackTrace();
        }
    }

private void addToGallery(String path) throws FileNotFoundException {
        MediaScannerConnection.scanFile(context, new String[]{

                        path},

                null, new MediaScannerConnection.OnScanCompletedListener() {

                    public void onScanCompleted(String path, Uri uri)

                    {

                        Log.e(TAG, "file" + path + " was scanned successfully");

                    }

                });

        Uri uri = Uri.parse("file:///" + path);
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
        context.sendBroadcast(intent);

        }

我确实有一个 VideoView 来显示它,这与我发现使用 volley 下载视频的代码示例有关。

https://github.com/coderminion/AndroidVolleyLib

标签: androidkotlinffmpegmp4h.264

解决方案


推荐阅读