流是电子后视镜传过来的,rtp里是h264。用ijkplay播放rtp流,出错Unable to receive RTP payload type 96 without an SDP file,如下图。意思缺少sdp 。电子后视镜开发人员用的vlc 打开个.sdp文件打开播放的。他说没问题。这.sdp文件,放在Android项目的哪里,怎么用Android ijkplay中的方法设置上去?不要c语言 的方法
根据您的描述,问题可能是由于您使用 IJKPlayer 播放 RTP 视频时未提供对应的 SDP 文件导致的。SDP 文件包含有关媒体流的详细信息(例如编解码器类型和参数、传输协议和端口等),没有 SDP 文件,IJKPlayer 就无法正确地解析 RTP 数据包并进行播放。
在 Android 中,您可以将 SDP 文件存储在 assets 目录下,然后使用 IjkMediaPlayer.setOption() 方法来设置 SDP 路径,示例如下:
java
IjkMediaPlayer mediaPlayer = new IjkMediaPlayer();
mediaPlayer.setDataSource("rtp://xxx.xxx.xxx.xxx:xxxxx");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", "32");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", "1");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", "fcc-rv32");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", "1");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", "48");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", "3000");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", "1");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_flags", "prefer_tcp");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", "2000000");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_timeout", "2000000");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "max_cached_audio_duration", "10");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "sync", "video");
mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "sdp_file", "sdcard/video.sdp");
mediaPlayer.prepareAsync();
注意,上述代码中的 sdcard/video.sdp 应替换为实际的 SDP 文件路径。另外,还需要在 AndroidManifest.xml 文件中添加以下权限:
xml
通过以上设置,您应该能够在 IJKPlayer 中正确载入和播放 RTP 视频流了。
Android ijkplayer播放rtsp直播流
可以借鉴下
https://blog.csdn.net/ydh7611/article/details/128196374
跟着重新操作
// 如果是rtsp协议,可以优先用tcp(默认是用udp)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
// 设置播放前的探测时间 1,达到首屏秒开效果
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1);
// 设置播放前的最大探测时间 (100未测试是否是最佳值)
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzemaxduration", 100L);
// 每处理一个packet之后刷新io上下文
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "flush_packets", 1L);
// 需要准备好后自动播放
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
// 是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0);
String url = mUri.toString();
if (!TextUtils.isEmpty(url) && url.contains("rtsp://")) { // 如果 rtmp 的协议, 修改 size 后会没有声音
// 播放前的探测Size,默认是1M, 改小一点会出画面更快
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 1024); //1024L)
}
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0);
// 设置是否开启环路过滤: 0开启,画面质量高,解码开销大,48关闭,画面质量差点,解码开销小
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48L);
// 跳过帧 ??
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_frame", 8);
// 视频帧处理不过来的时候丢弃一些帧达到同步的效果
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
https://blog.csdn.net/ydh7611/article/details/128196374
根据您提供的信息,您想在 Android 项目中使用 IJKPlayer 播放带有 RTP 流的 H264 视频,并解决缺少 SDP 文件的问题。以下是可能的解决方案:
获取 SDP 文件:首先,您需要获得带有正确 SDP 文件的视频流。根据您提到的电子后视镜开发人员使用 VLC 播放时没有问题,可以尝试联系他们获取 SDP 文件或者了解 SDP 文件的内容和格式。
将 SDP 文件添加到 Android 项目:一旦您获得了正确的 SDP 文件,您可以将其添加到 Android 项目中的适当位置。您可以将 SDP 文件放置在 assets
文件夹下,或者根据项目结构和需要放置在其他合适的位置。
使用 IJKPlayer 设置 SDP 文件:使用 IJKPlayer 播放器,您可以使用以下方法来设置 SDP 文件:
IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
String sdpFilePath = "file:///android_asset/your_sdp_file.sdp"; // 根据实际情况设置 SDP 文件的路径
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "rtsp_transport", "tcp");
ijkMediaPlayer.setDataSource(sdpFilePath);
ijkMediaPlayer.prepareAsync();
上述代码中,您需要将 your_sdp_file.sdp
替换为实际的 SDP 文件名,并确保 SDP 文件的路径是正确的。这样,IJKPlayer 将使用指定的 SDP 文件来播放 RTP 流。
请注意,以上代码仅是示例,您可能需要根据您的项目结构和需求进行相应的调整。
希望以上信息对您有所帮助,祝您成功解决播放 RTP 流缺少 SDP 文件的问题!
1、在Android应用程序的assets目录下创建一个.sdp文件
2、然后,使用AssetManager类来读取该文件并将其传递给IjkMediaPlayer
事例代码你网上搜索,一搜一大把,或者直接看ijkplayer的demo
我给个事例代码,大概就这么个意思
public static final String ASSET_SDP_FILE = "example.sdp"; // 请将此值更改为实际的.sdp文件名
...
AssetManager assetManager = getAssets();
String sdpString = null;
try {
InputStream is = assetManager.open(ASSET_SDP_FILE);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
sdpString = new String(buffer, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
if (sdpString != null) {
IjkMediaPlayer player = new IjkMediaPlayer();
player.setDataSource(sdpString);
...
}
为了解决这个问题,你需要找到包含SDP(Session Description Protocol)文件的SDP(Session Description Protocol)文件。通常情况下,SDP文件会包含有关音频、视频等多媒体元素的比特流信息,以及与这些比特流相关的元数据(如音频格式、视频帧率等)。
你可以将SDP文件保存在Android项目的资源文件夹中,例如res/sdp
文件夹。然后,在Android设备的设置中,你可以找到“声音”或“视频”选项,然后选择“使用默认媒体文件”。这将加载SDP文件,并允许Android设备解析该文件以播放音频或视频。
对于使用ijkplay播放rtp流的问题,你需要在ijkplay中设置正确的SDP文件,具体步骤可以参考文档中的示例代码,该文档提供了如何在ijkplay中设置SDP文件的方法。
另外,需要指出的是,SDP文件通常需要手动编写,并且需要与RTP协议的元数据匹配。因此,需要仔细阅读SDP文件的元数据,确保其与RTP协议的匹配。如果SDP文件中的元数据不正确,将无法正确播放音频或视频。
希望这些步骤能有所帮助。如果还有问题,请继续提问。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,需要了解SDP(Session Description Protocol)是一种描述多媒体会话的协议,主要用于实现网络多媒体会话,比如音频、视频等。而且,SDP和H.264并没有必然联系,SDP用于描述多媒体会话,而H.264是一种多媒体编码格式,两者目的和内容是不同的。
对于你的问题,错误提示"Unable to receive RTP payload type 96 without an SDP file"说明在接收RTP数据时,缺少SDP文件,需要先解析SDP文件,从而获取流媒体服务端的参数设置等信息,才能正确解析RTP数据并播放。
针对你的问题,你需要将传输的SDP文件保存到手机SD卡或应用目录下,然后在程序中读取SDP文件并解析,然后再使用IjkPlayer来播放RTP流。
以下是解析SDP文件并播放RTP流的示例代码:
import android.media.AudioFormat;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private static final String TAG = "MainActivity";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private MediaPlayer mMediaPlayer;
private IjkMediaPlayer mIjkMediaPlayer;
private ExecutorService mExecutorService;
private boolean mIsPlaying = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSurfaceView = findViewById(R.id.surface_view);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mExecutorService = Executors.newSingleThreadExecutor();
//初始化IjkMediaPlayer
mIjkMediaPlayer = new IjkMediaPlayer();
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//SurfaceView被创建后,启动播放流
startPlay();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//SurfaceView被销毁后,停止播放流
stopPlay();
}
//启动播放流
private void startPlay() {
//读取SDP文件
String sdpFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.sdp";
File sdpFile = new File(sdpFilePath);
if (sdpFile.exists()) {
try {
FileInputStream fis = new FileInputStream(sdpFile);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
buffer.append("\n");
}
reader.close();
fis.close();
String sdpContent = buffer.toString();
//解析SDP文件,获取流媒体参数设置等信息
//TODO: 在这里解析SDP文件,
//然后使用IjkMediaPlayer播放RTP流
//设置播放地址和SurfaceHolder
String playUrl = "rtp://127.0.0.1:8888";//RTP流地址
mIjkMediaPlayer.setDataSource(playUrl);
mIjkMediaPlayer.setSurface(mSurfaceHolder.getSurface());
//异步准备
mIjkMediaPlayer.prepareAsync();
mIjkMediaPlayer.setOnPreparedListener(new IjkMediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(IjkMediaPlayer ijkMediaPlayer) {
//准备完成后,开始播放
mIsPlaying = true;
mIjkMediaPlayer.start();
}
});
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, "SDP文件不存在", Toast.LENGTH_SHORT).show();
}
}
//停止播放流
private void stopPlay() {
if (mIsPlaying) {
mIjkMediaPlayer.stop();
mIsPlaying = false;
}
}
}
需要注意的是,以上示例代码仅作为演示用途,实际使用中还需要根据SDP文件的格式和内容进行解析。
如果我的回答解决了您的问题,请采纳!
以下答案由GPT-4.0Plus大模型与博主A努力中.......共同编写:
根据您的描述,ijkplay无法播放RTP流是因为没有SDP文件提供流信息,需要设置SDP文件才能正常播放。
在Android中,使用ijkplay播放RTP流的步骤如下:
java
String sdp = readAssetFile("sdp/stream.sdp");
java
IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "sdp_file", sdp);
java
ijkMediaPlayer.setDataSource("rtp://@192.168.1.10:5000");
java
String sdp = readAssetFile("sdp/stream.sdp");
IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "sdp_file", sdp);
ijkMediaPlayer.setDataSource("rtp://@192.168.1.10:5000");
ijkMediaPlayer.prepareAsync();
ijkMediaPlayer.start();