Android的原生MediaPlayer无法播放视频,但使用Dropbox的视频播放器可以播放。

3
我遇到了问题,无法使用Android的MediaPlayer播放某个.3gp文件(来自Dropbox链接)。然而,通过Dropbox Android应用程序,该文件神奇地可以无问题地播放。
我正在尝试使用以下方式进行播放:
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.dropbox.com/s/zpiqwmxka6llavt/SketchyFile.3gp"));
startActivity(intent);

我的清单包含

<uses-permission android:name="android.permission.INTERNET" />

会出现“无法播放此视频”错误。

error-screenshot

Logcat显示:

I/NuCachedSource2(89): new range: offset= 2245017
I/ChromiumHTTPDataSource(89): connect to https://dl.dropbox.com/0/view/a1crokuhpprsaeo/SketchyFile.3gp @2245017
I/NuCachedSource2(89): ERROR_END_OF_STREAM
E/MediaPlayer(3629): error (1, -2147483648)
E/MediaPlayer(3629): Error (1,-2147483648)
D/VideoView(3629): Error: 1,-2147483648

如果我尝试从Dropbox Android应用程序播放它,Dropbox的视频播放器可以轻松播放。

dropbox-success-screenshot

根据ffmpeg的ffprobe工具,我可以证实媒体类型不是Android中的奇特内容。 Dropbox是否执行了一些奇怪的转码技巧?有没有办法使这个过程类似地运行? 编辑:这里有更多关于DropBox编码技巧的见解。

你能直接从SD卡播放视频吗? - mbwasi
有没有可能只是认证问题,即视频不是公共的,因此仅对已登录的 Dropbox 应用程序可访问,但对于无 Dropbox 登录会话的其他 Android 组件而言,它不是作为原始 URL 交接的。 - Chris Stratton
不太可能,因为我故意将视频公开,并可以从新的浏览器会话中访问它。似乎涉及URL重定向(logcat中的dropbox URL不同),但将其设置为任何一个都没有任何区别。 - Nachi
2个回答

3
由于我既没有Dropbox应用程序源代码,也无法访问实际文件,因此以下是基于一些假设的最佳猜测。
该文件无法通过本地应用程序播放,因为它的格式无法在那里播放。你能否下载该文件,将其放入SD卡中,然后播放它?如果不能,则该手机不支持此格式。
为什么Dropbox播放器可以播放它?基于相同假设,我的猜测是Dropbox播放器会添加自己的解码库(例如ffmpeg),并将其置于jni之下。因此,它可以对其进行解码。
另一个可能的猜测: 您正在尝试流式播放3gp文件,这是不可能的。可能可以使用HTTP pd播放。同样,从SD卡中下载并播放它,如果它可以播放,则可能是这个问题。 这个文件可能没有提示,但它需要有。
Dropbox之所以可以播放这个文件,可能是因为Dropbox应用程序以某种方式通过其他API访问了文件末尾处的标头(你的魔法)?
再次强调,以上两点都是我根据常见问题猜测出来的,因为我既没有Dropbox应用程序源代码,也无法访问你的文件或者知道你是如何使用本地播放器播放视频的。也许以上的提示有所帮助。祝你好运!
编辑:问题见于:Nexus S无法在本地或http链接中播放给定文件。结果重新封装为mp4使Nexus S可以双向播放。这意味着某些Android设备的本地本地播放器中没有3gp支持。

感谢您的回复,我也认为这是Dropbox的巫术。我故意将视频文件公开以进行进一步分析,但它无法访问吗?https://www.dropbox.com/s/zpiqwmxka6llavt/SketchyFile.3gp - Nachi
你尝试过从本地SD卡播放吗?将其下载到手机上并播放。如果您正在尝试在3gp上进行流媒体传输,则不会起作用。该文件是可访问的,但未提示。因此,如果您正在进行伪流媒体传输,则可能需要提示。如果3gp文件未经提示且播放器不支持伪流媒体传输,则无法播放带有http链接的3gp文件。 - av501
从SD卡本地播放并没有得出明确的结论,它可以在Galaxy S2上播放但不能在Nexus S上播放(然而使用Dropbox在两者上都可以播放)。不过你最后的评论让我找对了方向。看起来文件是在mov容器中而不是mp4容器中,据我所知mov容器中的文件无法通过http可靠地流式传输。 - Nachi
Nachi,即使是mp4文件,除非它是伪流式传输,否则也无法进行流媒体传输。我认为你的问题在于它没有提示。 - av501
顺便提一下,Nexus S手机无法使用本地播放器播放此文件,我也可以证实。如果将其重新编码为mp4文件,则可以从SD卡上播放,也可以从另一台服务器作为HTTP链接播放(这两种方式之前都不可能)。这就意味着您的Dropbox应用程序具有对3gp的本机支持,而本机播放器则没有该支持。 - av501
太棒了!你使用了哪些FFmpeg参数? - Nachi

-1
你可以像下面这样使用 try-catch

try
{
  VideoView videoView = (VideoView) findViewById(R.id.VideoView);         
  MediaController mediaController = new MediaController(this);
  mediaController.setAnchorView(videoView);
  // Set Audio/Video
  String strfilename = "http://example.com/video.mp4";
  Uri video = Uri.parse(strfilename);
  videoView.setMediaController(mediaController);
  videoView.setVideoURI(video);
  videoView.start();   
} 
catch (Exception e) 
{
  //enter code here
  //Handle Errors
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接