5

我正在为需要流式传输 AAC 音频流的客户端开发应用程序。不幸的是,我对服务器上的流格式无能为力。我正在使用 Android 并发现 Android 的媒体播放器不支持原始 AAC 流(这就是我得到的)。我在Google Code上找到了一个支持它的项目(我用流测试了它),但它是 GPL 的,对我的客户不起作用。我对这类事情没有太多经验,所以如果我的想法不是很好,请原谅我。我知道安卓可以如果它位于 MP4 包装器中,则播放 AAC 编码的内容,因此我曾考虑在客户端动态创建 MP4 包装器,或者甚至只是动态地转换为另一种格式。这些是合理的选择吗?有人有更好的建议吗?

提前致谢!

编辑 换句话说,是否可以将来自 Web 服务器的原始 AAC 流实时放入 MP4 容器中?如果是这样,是否有人知道可以帮助我完成此过程的资源?

4

2 回答 2

3

我想知道你有没有想过解决这个问题?我也有类似的情况。我们有一个生成 AAC 文件的 Web 服务,虽然不是原始文件,但它们具有 ADTS 标头。Android 2.2 不能播放这些文件,虽然 android 2.1 可以,但很奇怪。这似乎是一个根源于 android 在 2.2 中切换到 stagefright 库进行媒体播放的问题。

AAC 文件在包装在 MP4 容器中时可以正常播放。我们已经使用 FAAC 在服务器端很容易地完成了这项工作(我意识到这对您的情况没有帮助)。不过,我们仍在调查使用 mp4 容器的许可问题。这需要版税吗?


回答我自己的问题...一位律师已经确认,将 mp4 容器用于 AAC 文件不需要许可。

于 2010-09-28T15:42:16.067 回答
1

我用 Google 的 ACCDECODER 试用了 4 个月,效果很好。我找到了它,在 2 天内我就能做到!:) 我在上一次Google I/O 2017上找到并看到了它

我可以建议使用EXOPLAYER而 不是MEDIAPLAYER 。这是一种更好的改进方法。我只使用 MediaPlayer 时遇到了同样的问题,但不久前我发现了 Exoplayer,现在我播放音频流 Acc、mp3、mpeg 等没有问题。我可以提供几个链接来检查它。

ExoPlayer 是一个开源项目,它不属于 Android 框架,与 Android SDK 分开分发。ExoPlayer 的标准音频和视频组件建立在 Android 的 MediaCodec API 之上,该 API 在 Android 4.1(API 级别 16)中发布。由于 ExoPlayer 是一个库,因此您可以通过更新应用程序轻松利用新功能。

ExoPlayer支持基于 HTTP 的动态自适应流式传输 (DASH)、SmoothStreaming 和通用加密等功能,MediaPlayer 不支持这些功能。它的设计易于定制和扩展。

这与 MediaPlayer 几乎相同,因为 Exoplayer 是从它扩展而来的。您可以看到很多差异以及实现它的简单方法。如果您需要更多帮助,请告诉我 :)

例如你有这个:

Media Player mediaPlayer = new MediaPlayer();
 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 mediaPlayer.setDataSource("http://your.url.com"); //add you url address
 ...
 mediaPlayer.prepare();
 mediaPlayer.start();

在 Exoplayer 你需要它:

    //  Create the player
        player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
        simpleExoPlayerView = new SimpleExoPlayerView(this);
        simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

//Set media controller
        simpleExoPlayerView.setUseController(true);
        simpleExoPlayerView.requestFocus();

// Bind the player to the view.
        simpleExoPlayerView.setPlayer(player);

ExoPlayer 示例代码:

public class MainActivity extends AppCompatActivity {


    private static final String TAG = "MainActivity";
    private SimpleExoPlayerView simpleExoPlayerView;
    private SimpleExoPlayer player;
    private ExoPlayer.EventListener exoPlayerEventListener;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.v(TAG,"portrait detected...");
        setContentView(R.layout.activity_main);



// 1. Create a default TrackSelector
        Handler mainHandler = new Handler();
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(mainHandler, videoTrackSelectionFactory);

// 2. Create a default LoadControl
        LoadControl loadControl = new DefaultLoadControl();

// 3. Create the player
        player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
        simpleExoPlayerView = new SimpleExoPlayerView(this);
        simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

//Set media controller
        simpleExoPlayerView.setUseController(true);
        simpleExoPlayerView.requestFocus();

// Bind the player to the view.
        simpleExoPlayerView.setPlayer(player);





//CHOOSE CONTENT: Livestream links may be out of date so find any m3u8 files online and replace:
//VIDEO FROM SD CARD:
//        String urimp4 = "/FileName.mp4";
//        Uri mp4VideoUri = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath()+urimp4);

//yachts livestream m3m8 file:
        Uri mp4VideoUri =Uri.parse("http://your.url.com");

//Random livestream file:
//        Uri mp4VideoUri =Uri.parse("http://your.url.com");

//Sports livestream file:
//        Uri mp4VideoUri =Uri.parse("http://your.url.com");




// Measures bandwidth during playback. Can be null if not required.
        DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
//Produces DataSource instances through which media data is loaded.
//        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "exoplayer2example"), bandwidthMeterA);

//Produces Extractor instances for parsing the media data.
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

//This is the MediaSource representing the media to be played:
//FOR SD CARD SOURCE:
//        MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null);

//FOR LIVESTREAM LINK:
        MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
        final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);


// Prepare the player with the source.
        player.prepare(loopingSource);



        player.addListener(new ExoPlayer.EventListener() {
            @Override
            public void onLoadingChanged(boolean isLoading) {
                Log.v(TAG,"Listener-onLoadingChanged...");

            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                Log.v(TAG,"Listener-onPlayerStateChanged...");

            }

            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest) {
                Log.v(TAG,"Listener-onTimelineChanged...");

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {
                Log.v(TAG,"Listener-onPlayerError...");
                player.stop();
                player.prepare(loopingSource);
                player.setPlayWhenReady(true);
            }

            @Override
            public void onPositionDiscontinuity() {
                Log.v(TAG,"Listener-onPositionDiscontinuity...");

            }
        });
        player.setPlayWhenReady(true);

    }//End of onCreate




    @Override
    protected void onStop() {
        super.onStop();
        Log.v(TAG,"onStop()...");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v(TAG,"onStart()...");

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.v(TAG,"onResume()...");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.v(TAG,"onPause()...");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v(TAG,"onDestroy()...");
        player.release();

    }

}

这是一个简短的例子,如果您正在寻找其他东西或需要更多帮助,请告诉我!我在这里!我愿意提供帮助,因为我知道当您在谷歌搜索和搜索 以及出现的任何内容时的感觉!:) 小心!!

于 2017-06-21T13:34:43.993 回答