我试图开发一个电视播放器与比特率选项(管理视频质量像在YouTube)我的播放器播放所有视频,除了直播流(电视频道从链接)。
我尝试过的解决方案:
回答1:在Android上使用Google Exoplayer播放HLS流时出错
回答2:Exoplayer v2,实时视频流
我在StackOverflow上尝试了一些其他的答案,读了一些博客,但没有帮助。
下面是我的代码,如果有人能帮我解决这个问题。以下活动还包含管理流速度的代码
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.ui.PlayerView;
public class MainActivity extends AppCompatActivity {
private boolean isShowingTrackSelectionDialog;
private DefaultTrackSelector trackSelector;
//Below line is for video speed option
String[] speed = {"0.25x","0.5x","Normal","1.5x","2x"};
//Below ARE WORKING URLS becuase video is present on server and is not live
//String url1 = "https://5b44cf20b0388.streamlock.net:8443/vod/smil:bbb.smil/playlist.m3u8";
// String url1 = "https://5b44cf20b0388.streamlock.net:8443/vod/smil:ed.smil/playlist.m3u8";
//String url1 = "https://5b44cf20b0388.streamlock.net:8443/vod/smil:sintel-hd.smil/playlist.m3u8";
//Below are urls don't work because these are for tv channels
// String url1 = "https://stream.commec.tv/iframe/b/169562/c/5707742";
String url1 = "http://app.pakistanVision.tv:1935/live/PTVnews/player.m3u8";
//String url1 = "http://cdn.ebound.tv/tv/expressentertainment/chunks.m3u8";
//String url1 = "https://s3-us-west-2.amazonaws.com/hls-playground/hls.m3u8";
// String url1 = "http://192.168.0.102:8001/1:0:19:4E89:14:70:1680000:0:0:0:";
// String url1 = "http://cspan1-lh.akamaihd.net/i/cspan1_1@304727/index_1000_av-p.m3u8";
PlayerView playerView;
SimpleExoPlayer simpleExoPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
trackSelector = new DefaultTrackSelector(this);
simpleExoPlayer = new SimpleExoPlayer.Builder(this).setTrackSelector(trackSelector).build();
playerView = findViewById(R.id.exoPlayerView);
playerView.setPlayer(simpleExoPlayer);
/*When used the below code it doesn't work for anything
simpleExoPlayer =
new SimpleExoPlayer.Builder(this)
.setMediaSourceFactory(
new DefaultMediaSourceFactory(this).setLiveTargetOffsetMs(5000))
.build();
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(url1)
.setLiveMaxPlaybackSpeed(1.02f)
.build();
simpleExoPlayer.setMediaItem(mediaItem); up-to here*/
simpleExoPlayer.addMediaItem(mediaItem);
simpleExoPlayer.prepare();
simpleExoPlayer.play();
ImageView farwordBtn = playerView.findViewById(R.id.fwd);
ImageView rewBtn = playerView.findViewById(R.id.rew);
ImageView setting = playerView.findViewById(R.id.exo_track_selection_view);
ImageView speedBtn = playerView.findViewById(R.id.exo_playback_speed);
TextView speedTxt = playerView.findViewById(R.id.speed);
speedBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Set Speed");
builder.setItems(speed, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// the user clicked on colors[which]
if (which==0){
speedTxt.setVisibility(View.VISIBLE);
speedTxt.setText("0.25X");
PlaybackParameters param = new PlaybackParameters(0.5f);
simpleExoPlayer.setPlaybackParameters(param);
} if (which==1){
speedTxt.setVisibility(View.VISIBLE);
speedTxt.setText("0.5X");
PlaybackParameters param = new PlaybackParameters(0.5f);
simpleExoPlayer.setPlaybackParameters(param);
}
if (which==2){
speedTxt.setVisibility(View.GONE);
PlaybackParameters param = new PlaybackParameters(1f);
simpleExoPlayer.setPlaybackParameters(param);
}
if (which==3){
speedTxt.setVisibility(View.VISIBLE);
speedTxt.setText("1.5X");
PlaybackParameters param = new PlaybackParameters(1.5f);
simpleExoPlayer.setPlaybackParameters(param);
}
if (which==4){
speedTxt.setVisibility(View.VISIBLE);
speedTxt.setText("2X");
PlaybackParameters param = new PlaybackParameters(2f);
simpleExoPlayer.setPlaybackParameters(param);
}
}
});
builder.show();
}
});
farwordBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
simpleExoPlayer.seekTo(simpleExoPlayer.getCurrentPosition() + 10000);
}
});
rewBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
long num = simpleExoPlayer.getCurrentPosition() - 10000;
if (num < 0) {
simpleExoPlayer.seekTo(0);
} else {
simpleExoPlayer.seekTo(simpleExoPlayer.getCurrentPosition() - 10000);
}
}
});
ImageView fullscreenButton = playerView.findViewById(R.id.fullscreen);
fullscreenButton.setOnClickListener(new View.OnClickListener() {
@SuppressLint("SourceLockedOrientationActivity")
@Override
public void onClick(View view) {
int orientation = MainActivity.this.getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// code for portrait mode
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
// code for landscape mode
Toast.makeText(MainActivity.this, "Land", Toast.LENGTH_SHORT).show();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
});
findViewById(R.id.exo_play).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
simpleExoPlayer.play();
}
});
findViewById(R.id.exo_pause).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
simpleExoPlayer.pause();
}
});
simpleExoPlayer.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int state) {
if (state == ExoPlayer.STATE_ENDED) {
}
}
});
playerView.setControllerVisibilityListener(new PlayerControlView.VisibilityListener() {
@Override
public void onVisibilityChange(int visibility) {
}
});
setting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isShowingTrackSelectionDialog
&& TrackSelectionDialog.willHaveContent(trackSelector)) {
isShowingTrackSelectionDialog = true;
TrackSelectionDialog trackSelectionDialog =
TrackSelectionDialog.createForTrackSelector(
trackSelector,
/* onDismissListener= */ dismissedDialog -> isShowingTrackSelectionDialog = false);
trackSelectionDialog.show(getSupportFragmentManager(), /* tag= */ null);
}
}
});
}
}
以上JAVA代码的XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fram"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/exoPlayerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
app:controller_layout_id="@layout/ustom_controls"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:resize_mode="fixed_width"
app:show_buffering="when_playing">
</com.google.android.exoplayer2.ui.PlayerView>
</FrameLayout>
我的身材。格雷德尔:
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.stremobuilders321.stremoplayer"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation'com.google.android.exoplayer:exoplayer:2.14.1'
implementation 'com.android.support:multidex:1.0.3'
}
除了以上所有内容之外,我还使用自定义控件xml布局(用于媒体播放器按钮)和一个控制比特率的类,如果需要,我也将提供这两个类。
我的应用程序给出的错误是:E/ExoPlayerImplInternal:播放错误com.google.Androidexoplayer2。ExoPlaybackException:源错误
原因:com.google.Androidexoplayer2。上游HttpDataSource$HttpDataSource异常:无法连接
它适用于服务器上的存储视频,但不适用于直播电视频道给出上述错误。
尝试设置mime类型
MediaItem mediaItem = new MediaItem.Builder()
.setUri(uri)
.setMimeType(MimeTypes.APPLICATION_M3U8)
.build();
您可以尝试在https://drive.google.com/file/d/0Byr1H33Pe7u-MW93UUpmMUhGTTQ/view下载此示例并修改Uri
video_url = "http://cspan1-lh.akamaihd.net/i/cspan1_1@304727/index_1000_av-p.m3u8";
注意:一些m3u8文件由于格式不正确而无法播放。请检查此处支持的格式https://google.github.io/ExoPlayer/supported-formats.html
13. 视频直播防盗链规则 13.1. 鉴权构造 用户访问加密防盗链 URL 地址构成 http://DomainName/AppName/StreamName?sign=xxxxxxxxx&stTime=xxxxxxx k=md5(“key”+“/AppName/”+“StreamName”+t) 参数 描述 key 后台生成的秘钥 AppName 流所属应用名称 StreamName 流名称
如何在Android中通过任何视频链接播放视频(例如—https://youtu.be/SiD77g9KfhA“也可以是另一个媒体门户的另一个视频链接)。我尝试过这样做,但遇到了一个错误。 我的代码 错误。
我正在开发一个应用程序,我使用了谷歌的ExoPlayer,它工作起来很有魅力,现在我想在我的应用程序中添加RTSP支持,但使用ExoPlayer我无法播放,请任何人都可以帮我,如果有人有其他选择,请与我分享。 日志 E/ExoPlayerImplInternal:源错误。网蝴蝶电视。rtmp_客户端。RtmpClient$RtmpIOException at net。蝴蝶电视。rtmp_客户端。R
我想做现场视频流。例如,有讨论。有人在录下来。我希望视频记录出现在我的网页上。我想用HTML5来做这件事。我不知道有没有可能,但有人试过吗?提前感谢!
问题内容: 我想从某些流式视频资源(例如you- tube或metacafe.com)中获取确切的视频链接,因为没有直接的视频链接可用。如何解析视频链接。还有如何使用Java将流视频从http url下载到本地系统? 谢谢! 问题答案: 我以前使用了一个名为HTMLParser的库。它可以读取html输入并生成HTML节点。然后,您可以分析并检索您喜欢的节点。
我不知道如何得到这样一个URL和我结束在这里。这是否意味着即使视频是我自己的,我也不能从YouTube上流媒体?(特别是现场视频)如果我可以的话,我怎么能为我的视频获得这样一个URL呢?