android原生MediaPlayer播放本地的m3u8
背景
遇到某个需求,需要播放百度网盘的视频。但是通过百度网盘的sdk获取到的视频url是由若干个ts片段组成的m3u8播放源。然后把这个m3u8的播放源放在本地,也就是说m3u8是一个本地播放源。那么如何去播放呢?这边引进一个http轻量级的服务器NanoHttpd。
选择播放器
目前市场上流行的播放器,比如ijkPlay,是可以直接播放本地的m3u8,但是android原生的播放器却不能。那么如何去播放呢?这边引进一个http轻量级的服务器NanoHttpd。
什么是NanoHttpd?
NanoHTTPD是一个免费、轻量级的HTTP服务器,可以很好地嵌入到Java程序中。支持 GET, POST, PUT, HEAD 和 DELETE 请求,支持文件上传,占用内存很小。可轻松定制临时文件使用和线程模型。
git地址:
https://github.com/NanoHttpd/nanohttpd
下面看看NanoHttpd的使用情况
在build.gradle文件中引入nanohttpd
implementation ‘org.nanohttpd:nanohttpd:2.3.1’
由于9.0以上禁止使用未加密的连接,所以在res下添加xml文件夹,并把network_security_config.xml放到该文件夹下,并在AndroidManifest.xml的application中添加android:networkSecurityConfig="@xml/network_security_config"network_security_config文件的具体内容如下:
127.0.0.1 localhost
如果.m3u8的文件是放在sdcard中需要在AndroidManifest.xml下添加相关的读写权限,放在data/data中则不需要
- 添加完以上配置后,就可以使用了,具体使用可参考LocalServer:
import android.util.Log;import java.io.File;import java.io.FileInputStream;import fi.iki.elonen.NanoHTTPD;public class LocalServer extends NanoHTTPD { private static String TAG = "CcLocalServer"; private static final String MIME_TYPE_M3U8 = "video/x-mpegURL"; // 端口号 public static final int PORT = 9999; public LocalServer() { // 端口号 super(PORT); Log.d(TAG, "---CcLocalServer---"); } @Override public Response serve(IHTTPSession session) { // 获取请求的url String url = session.getUri(); Log.d(TAG, "请求URL:" + url); try { File file = new File(url); //判断本地的文件是否存在 if (file.exists()) { //直接返回m3u8的文件格式 return newChunkedResponse(Response.Status.OK, MIME_TYPE_M3U8, new FileInputStream(file)); } else { return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/html", "文件不存在:" + url); } } catch (Exception e) { e.printStackTrace(); return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/html", "文件不存在:" + url); } }}
activity中如何使用呢?
注意:m3u8文件和文件的存放位置由使用者自己决定
import android.media.AudioManager;import android.media.MediaPlayer;import android.os.Bundle;import android.os.Environment;import android.text.TextUtils;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import com.example.mediaplaydome.server.LocalServer;public class MediaPlayerActivity extends AppCompatActivity { private static final String TAG = "MediaPlayerActivity"; private SurfaceHolder surfaceHolder; private SurfaceView surfaceView; private MediaPlayer mediaPlayer; private LocalServer mMyServer = new LocalServer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getSupportActionBar().hide(); setContentView(R.layout.activity_media_player); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); startLocalServer(); startPlayVideo(); } private void startLocalServer() { try { // 开启本地代理 mMyServer.start(); } catch (Exception e) { Log.e(TAG, "server start failed", e); } } private void startPlayVideo() { String url = getHttpUrl(Environment.getExternalStorageDirectory().getPath() + "/local_m3u8/test.m3u8"); Log.i(TAG, "当前的url:" + url); mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); try { mediaPlayer.setDataSource(url); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) { mediaPlayer.setDisplay(surfaceHolder); } @Override public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) { } @Override public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) { } }); mediaPlayer.prepare(); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); mediaPlayer.setLooping(true); } }); } catch (Exception e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); //关闭服务 if (mMyServer != null) { mMyServer.closeAllConnections(); mMyServer = null; Log.e(TAG, "app destory, so server close"); } } public static String getHttpUrl(String localUrl) { if (TextUtils.isEmpty(localUrl)) { return localUrl; } return String.format("http://127.0.0.1:%d%s", LocalServer.PORT, localUrl); }}
来源地址:https://blog.csdn.net/L779442863/article/details/126587440
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341