Android 媒体流错误? java.io.FileNotFoundException:没有内容提供者:http://

Posted

技术标签:

【中文标题】Android 媒体流错误? java.io.FileNotFoundException:没有内容提供者:http://【英文标题】:Android Media Stream Error? java.io.FileNotFoundException: No content provider :http:// 【发布时间】:2017-06-25 16:01:47 【问题描述】:

我跟随this在android中播放流广播

这里它工作正常,但点击后播放器加载有点慢我需要等待 30 多秒的时间

但我在控制台中收到此错误

MediaPlayer: setDataSource IOException happend : 
java.io.FileNotFoundException: No content provider: http://www.example.com:8000/live.ogg
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1074)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:927)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:854)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1087)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1061)
at org.oucho.radio.Player.playLaunch(Player.java:237)
at org.oucho.radio.Playlist.onPostExecute(Playlist.java:98)
at org.oucho.radio.Playlist.onPostExecute(Playlist.java:35)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5951)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)

在链接中你可以看到player等所有文件

由于这个错误,我的直播很慢。请任何人帮助我处理这种类型

这里的错误与 .ogg 文件无关,我尝试使用 .mp3 和只是 /live

http://www.example.com:8000/beet.ogg
http://www.example.com:8000/mouthorgan.mp3
http://www.example.com:8000/live

音频正在播放,但在出现此错误后它需要大约 30 秒时间有时需要太长时间......当我播放时它显示此错误,然后它连接到服务器......并播放

请帮我解决这个问题

【问题讨论】:

只需将 HTTP 更改为 HTTPS。更多细节在这里:***.com/questions/45940861/… 【参考方案1】:

转到此文件https://github.com/Old-Geek/Radio/blob/master/app/src/main/java/org/oucho/radio/Player.java#L234 并更改

player.setDataSource(context, Uri.parse(url));

player.setDataSource(url)

问题在于void setDataSource (String path) 设置要使用的数据源(文件路径或http/rtsp URL)。

path String:文件的路径,或者你要播放的流的http/rtsp URL

github 代码使用void setDataSource (Context context, Uri uri),它假定uriContentProvider 的某种形式

上下文上下文:解析 Uri 时使用的上下文 uri Uri:你要播放的数据的Content URI

【讨论】:

谢谢@Anurag Singh .. 现在错误消失了但是我收到了这个警告的02-13 15:24:20.233 16769-16787/org.sss.text.liveradio D/MediaHTTPConnection: filterOutInternalHeaders: key=User-Agent, val= stagefright/1.2 (Linux;Android 5.1.1) 02-13 15:24:20.243 16769-16786/org.sss.text.liveradio D/MediaHTTPConnection: proxy null port 0 02-13 15:24:38.203 16769-16769/org.sss.text.liveradio E/MediaPlayer: Should have subtitle controller already set 02-13 15:24:54.743 16769-16769/org.sss.text.liveradio E/MediaPlayer-JNI: QCMediaPlayer mediaplayer NOT present 和它的播放相同30sec dilay 谢谢您的回答有效....但仍然有一点延迟,我会检查并确认赏金,,,, 我需要为你们俩伸张正义所以几乎你们俩都帮助了我所以我已经分发了他们的赏金并回答感谢您在我的问题上花费您的精力和时间【参考方案2】:

java.io.FileNotFoundException:没有内容提供者: http://www.example.com:8000/live.ogg

因为它尝试根据上下文从设备内容提供者作为文件加载,并且您作为 URL 传递。

似乎您的问题在于将数据源设置为媒体播放器。当您尝试在没有上下文的情况下播放 setDataSource 方法所需的 url 或流式传输时。

我在播放直播时遇到了同样的问题。下面的代码解决了我的问题。

播放器屏幕

        public class PlayerScreen extends Activity 
        @Override
        protected void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);
            setContentView(R.layout.player);
            startService(new Intent(this, MediaPlayerService.class));
            findViewById(R.id.btnChangeTrack).setOnClickListener(clickListener);
            findViewById(R.id.btnStartMediaPlayer).setOnClickListener(clickListener);
            findViewById(R.id.btnStopMediaPlayer).setOnClickListener(clickListener);
            ToggleButton toggleButton = (ToggleButton) findViewById(R.id.togglePauseResume);
            toggleButton.setOnCheckedChangeListener(checkedChangeListener);
            /*
            * To get url which is passing from the previous activity listitem click.
            * If url which is pass from listitem click is not empty it will start player
            * */
            String url = getIntent().getStringExtra("url");
            if (!TextUtils.isEmpty(url))
                startMediaPlayer(url);

        

        private ToggleButton.OnCheckedChangeListener checkedChangeListener = new ToggleButton.OnCheckedChangeListener() 
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
                if (!isChecked) 
                    Intent intent = new Intent();
                    intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
                    intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.PAUSE_MEDIA_PLAYER);
                    sendBroadcast(intent);
                 else 
                    Intent intent = new Intent();
                    intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
                    intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.RESUME_MEDIA_PLAYER);
                    sendBroadcast(intent);
                
            
        ;
        private View.OnClickListener clickListener = new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                Intent intent;
                switch (v.getId()) 
                    case R.id.btnChangeTrack:
                        intent = new Intent();
                        intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
                        intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.CHANGE_PLAYER_TRACK);
                        intent.putExtra(MediaPlayerService.PLAYER_TRACK_URL, "http://www.example.com:8000/live");
                        sendBroadcast(intent);
                        break;
                    case R.id.btnStartMediaPlayer:
                        startMediaPlayer("http://www.example.com:8000/beet.ogg");
//startMediaPlayer("http://108.163.197.114:8071/listen.pls");
                        break;
                    case R.id.btnStopMediaPlayer:
                        intent = new Intent();
                        intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
                        intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.STOP_MEDIA_PLAYER);
                        sendBroadcast(intent);
                        break;

                
            
        ;

        @Override
        protected void onResume() 
            super.onResume();
            registerReceiver(receiverFromservice, new IntentFilter(MediaPlayerService.SERVICE_TO_ACTIVITY));
        

        private String currentPlayerStatus = "N/A";
        private BroadcastReceiver receiverFromservice = new BroadcastReceiver() 
            @Override
            public void onReceive(Context context, Intent intent) 
                String action = intent.getAction();
                if (MediaPlayerService.SERVICE_TO_ACTIVITY.equalsIgnoreCase(action)) 
                    /*
                    * To get current status of player
                    * */
                    currentPlayerStatus = intent.getStringExtra(MediaPlayerService.PLAYER_STATUS_KEY);
                    Log.e("Player Mode", "" + currentPlayerStatus);
                
            
        ;

        @Override
        protected void onPause() 
            super.onPause();
            unregisterReceiver(receiverFromservice);
        

        /**
         * TO start media player.It will send broadcast to Service & from service player will start
         *
         * @param url
         */
        public void startMediaPlayer(String url) 
            Intent intent = new Intent();
            intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
            intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.PLAY_MEDIA_PLAYER);
            intent.putExtra(MediaPlayerService.PLAYER_TRACK_URL, url);
            sendBroadcast(intent);
        
    

MediaPlayerService

public class MediaPlayerService extends Service 
    public static final String BROADCAST_TO_SERVICE = "com.mediaplayer.playerfunction";
    public static final String SERVICE_TO_ACTIVITY = "com.mediaplayer.currentPlayerStatus";
    public static final String PLAYER_FUNCTION_TYPE = "playerfunction";
    public static final String PLAYER_TRACK_URL = "trackURL";
    public static final int PLAY_MEDIA_PLAYER = 1;
    public static final int PAUSE_MEDIA_PLAYER = 2;
    public static final int RESUME_MEDIA_PLAYER = 3;
    public static final int STOP_MEDIA_PLAYER = 4;
    public static final int CHANGE_PLAYER_TRACK = 5;
    public static final String PLAYER_STATUS_KEY = "PlayerCurrentStatus";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) 
        return null;
    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        IntentFilter intentFilter = new IntentFilter(BROADCAST_TO_SERVICE);
        registerReceiver(playerReceiver, intentFilter);
        if (mPlayer != null && mPlayer.isPlaying()) 
            sendPlayerStatus("playing");
        
        return START_STICKY;
    

    private BroadcastReceiver playerReceiver = new BroadcastReceiver() 
        @Override
        public void onReceive(Context context, Intent intent) 
            String action = intent.getAction();
            if (BROADCAST_TO_SERVICE.equalsIgnoreCase(action)) 
                String trackURL = intent.hasExtra(PLAYER_TRACK_URL) ? intent.getStringExtra(PLAYER_TRACK_URL) : "";
                int function = intent.getIntExtra(PLAYER_FUNCTION_TYPE, 0);
                switch (function) 
                    case CHANGE_PLAYER_TRACK:
                        changeTrack(trackURL);
                        break;
                    case STOP_MEDIA_PLAYER:
                        stopPlayer();
                        break;
                    case PLAY_MEDIA_PLAYER:
                        startMediaPlayer(trackURL);
                        break;
                    case PAUSE_MEDIA_PLAYER:
                        pausePlayer();
                        break;
                    case RESUME_MEDIA_PLAYER:
                        resumePlayer();
                        break;
                

            
        
    ;
    private MediaPlayer mPlayer;

    private void pausePlayer() 
        if (mPlayer != null && mPlayer.isPlaying()) 
            mPlayer.pause();
            sendPlayerStatus("pause");
        
    

    private void resumePlayer() 
        if (mPlayer != null && !mPlayer.isPlaying()) 
            mPlayer.start();
            sendPlayerStatus("playing");
        
    

    private void changeTrack(String url) 
        stopPlayer();
        startMediaPlayer(url);

    

    private void stopPlayer() 
        if (mPlayer != null) 
            mPlayer.stop();
            mPlayer.release();
            mPlayer = null;
            sendPlayerStatus("stopped");

        
    

    public void startMediaPlayer(String url) 
        if (TextUtils.isEmpty(url))
            return;
        if (mPlayer == null)
            mPlayer = new MediaPlayer();
        try 
            mPlayer.setDataSource(url);
            mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() 

                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) 
                    if (extra == MediaPlayer.MEDIA_ERROR_SERVER_DIED
                            || extra == MediaPlayer.MEDIA_ERROR_MALFORMED) 
                        sendPlayerStatus("erroronplaying");
                     else if (extra == MediaPlayer.MEDIA_ERROR_IO) 
                        sendPlayerStatus("erroronplaying");
                        return false;
                    
                    return false;
                
            );
            mPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() 

                public void onBufferingUpdate(MediaPlayer mp, int percent) 
                    Log.e("onBufferingUpdate", "" + percent);

                
            );
            mPlayer.prepareAsync();
            mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 

                public void onPrepared(MediaPlayer mp) 
                    mPlayer.start();
                    sendPlayerStatus("playing");
                
            );
            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 

                @Override
                public void onCompletion(MediaPlayer mp) 
                    Log.e("onCompletion", "Yes");
                    sendPlayerStatus("completed");
                
            );
            mPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() 
                @Override
                public boolean onInfo(MediaPlayer mp, int what, int extra) 
                    return false;
                
            );
         catch (IllegalArgumentException e) 
            e.printStackTrace();
         catch (IllegalStateException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
    

    private void sendPlayerStatus(String status) 
        Intent intent = new Intent();
        intent.setAction(SERVICE_TO_ACTIVITY);
        intent.putExtra(PLAYER_STATUS_KEY, status);
        sendBroadcast(intent);
    

player.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_>

    <TextView
        android:id="@+id/section_label"
        android:layout_
        android:layout_
        android:layout_below="@+id/ab_tool"
        android:text="Home" />

    <Button
        android:id="@+id/btnStartMediaPlayer"
        android:layout_
        android:layout_
        android:layout_below="@+id/section_label"
        android:text="Start Player" />


    <ToggleButton
        android:id="@+id/togglePauseResume"
        android:layout_
        android:layout_
        android:layout_below="@+id/btnStartMediaPlayer"
        android:checked="true"
        android:textOff="Resume"
        android:textOn="Pause" />

    <Button
        android:id="@+id/btnChangeTrack"
        android:layout_
        android:layout_
        android:layout_below="@+id/togglePauseResume"
        android:text="Chanage Track" />

    <Button
        android:id="@+id/btnStopMediaPlayer"
        android:layout_
        android:layout_
        android:layout_below="@+id/btnChangeTrack"
        android:text="STOP" />
</RelativeLayout>

清单

<activity android:name=".PlayerScreen">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />


        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<service android:name=".MediaPlayerService"></service>

要从流式 url 标头数据中获取数据,您可以 [检查此答案][2]

出于测试目的,我在这里使用了两个网址

更新 玩家活动

public class PlayerScreen extends Activity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.player);
        startService(new Intent(this, MediaPlayerService.class));
        /*
        * To get url which is passing from the previous activity listitem click.
        * If url which is pass from listitem click is not empty it will start player
        * */
        String url = getIntent().getStringExtra("url");
        if (!TextUtils.isEmpty(url))
            startMediaPlayer(url);

    

    @Override
    protected void onResume() 
        super.onResume();
        registerReceiver(receiverFromservice, new IntentFilter(MediaPlayerService.SERVICE_TO_ACTIVITY));
    

    private String currentPlayerStatus = "N/A";
    private BroadcastReceiver receiverFromservice = new BroadcastReceiver() 
        @Override
        public void onReceive(Context context, Intent intent) 
            String action = intent.getAction();
            if (MediaPlayerService.SERVICE_TO_ACTIVITY.equalsIgnoreCase(action)) 
                /*
                * To get current status of player
                * */
                currentPlayerStatus = intent.getStringExtra(MediaPlayerService.PLAYER_STATUS_KEY);
                Log.e("Player Mode", "" + currentPlayerStatus);
            
        
    ;

    @Override
    protected void onPause() 
        super.onPause();
        unregisterReceiver(receiverFromservice);
    

    /**
     * TO start media player.It will send broadcast to Service & from service player will start
     *
     * @param url
     */
    public void startMediaPlayer(String url) 
        Intent intent = new Intent();
        intent.setAction(MediaPlayerService.BROADCAST_TO_SERVICE);
        intent.putExtra(MediaPlayerService.PLAYER_FUNCTION_TYPE, MediaPlayerService.PLAY_MEDIA_PLAYER);
        intent.putExtra(MediaPlayerService.PLAYER_TRACK_URL, url);
        sendBroadcast(intent);
    

如果有任何事情请告诉我。

【讨论】:

谢谢@user1140237 先生...我认为这很好但我需要检查我的收音机服务现在它已关闭.. 需要 2 天才能续订...如果可能的话你能建议我如何使用this in TabLayout @MLN 你可以使用任何流媒体 url 来测试上面的代码,比如来自直播 streaming url。具有 mp3 或 ogg 编解码器的 URL。 谢谢 git-hub 是否有任何代码示例或类似您的代码的东西...在这里我尝试丢失一些文件...实际上我的代码延迟了 30 秒,所以有任何代码 @MLN nope theres not sample on git sorry...但是缺少什么让我知道 我在isPlaying 收到错误无法解决.. 以及MediaPlayerService 中的其他一些问题,所以我要求提供任何 github 或示例等进行测试【参考方案3】:

在 Android 9+ 上,清除网络 http 流量可能会导致此问题。检查这个:Android 8: Cleartext HTTP traffic not permitted

【讨论】:

【参考方案4】:

如果此 Internet 权限不在 Manifest.xml 中,也会发生此错误

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

【讨论】:

以上是关于Android 媒体流错误? java.io.FileNotFoundException:没有内容提供者:http://的主要内容,如果未能解决你的问题,请参考以下文章

在没有 MediaPlayer 的情况下在 android 上播放实时媒体流

Android MediaPlayer 流错误:100:MEDIA_ERROR_SERVER_DIED

Android/iOS:通过流混合改善实时流媒体体验

Android/iOS:通过流混合改善实时流媒体体验

Android流媒体开发之路二:NDK开发Android端RTMP直播推流程序

android媒体播放器替代品?