-
下载抖音直播视频功能,代码比较简单,参考了某博客用python实现的的下载功能,原文地址:https://www.cnblogs.com/wuyongcong/p/12627370.html
-
第一步:获取抖音直播分享短链接对应的长链接
-
-
fun startALaunch(baseUrl: String, onConnectionCallBack: OnConnectionCallBack) {
-
job = GlobalScope.launch {
-
var con: HttpURLConnection = URL(baseUrl).openConnection() as HttpURLConnection
-
con.instanceFollowRedirects = false
-
con.connectTimeout = 5000
-
val url: String = con.getHeaderField("Location")
-
con.disconnect()
-
onConnectionCallBack.onBack(url)
-
}
-
}
-
- 第二部:通过接口,请求直播推流地址
-
-
fun getRtmpPullUrl(roomID: String) {
-
if(!TextUtils.isEmpty(roomID)) {
-
OkGo.get<String>("https://webcast-hl.amemv.com/webcast/room/reflow/info/")
-
.params("room_id", roomID)
-
.params("live_id", 1)
-
.execute(object : StringCallback() {
-
override fun onSuccess(response: Response<String>?) {
-
if (response != null) {
-
logged("response:" + response.body())
-
var data =
-
getMap(response.body().toString()).get("data") as Map<String, Any>
-
var room = data.get("room") as Map<String, Any>
-
var stream_url = room.get("stream_url") as Map<String, Any>
-
var rtmp_pull_url = stream_url.get("rtmp_pull_url")
-
var msg = Message()
-
msg.what = 4
-
msg.obj = rtmp_pull_url
-
handler.sendMessage(msg)
-
}
-
}
-
})
-
}
-
}
-
- 完整代码:
-
-
class MainActivity : AppCompatActivity() {
-
var job: Job? = null
-
val re = Regex("""(\d{19})""")
-
val gson = Gson()
-
var handler = object :Handler(){
-
override fun handleMessage(msg: Message) {
-
super.handleMessage(msg)
-
when(msg.what){
-
0 ->{
-
textview.setText("直播短链接:"+msg.obj)
-
}
-
1 ->{
-
initPostUrl(msg.obj as String)
-
}
-
2 ->{
-
initRtmpPullUrl(msg.obj as String)
-
}
-
3 ->{
-
getRtmpPullUrl(msg.obj as String)
-
}
-
4 ->{
-
textview3.setText("推流地址:${msg.obj}")
-
startForBrowser(msg.obj as String)
-
}
-
}
-
}
-
}
-
override fun onCreate(savedInstanceState: Bundle?) {
-
super.onCreate(savedInstanceState)
-
setContentView(R.layout.activity_main )
-
initBaseString()
-
initRid()
-
}
-
/**
-
* 获取直播短链接
-
*/
-
fun initBaseString(){
-
edittext.addTextChangedListener(object :TextWatcher{
-
override fun afterTextChanged(s: Editable?) {
-
var baseString = edittext.text.toString()
-
//判断分享过来的是否是抖音的短链接
-
if(baseString.contains(" https://v.douyin.com")) {
-
var msg = Message()
-
msg.what = 0;
-
msg.obj = baseString.split("!")[1] //拆分分享短连接的文案、链接
-
handler.sendMessage(msg)
-
}
-
}
-
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
-
}
-
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
-
}
-
})
-
}
-
/**
-
* 获取直播长链接
-
*/
-
fun initRid(){
-
button.setOnClickListener(object : View.OnClickListener {
-
override fun onClick(v: View?) {
-
var rid: String = textview.text.toString().replace("直播短链接:","")
-
if(!TextUtils.isEmpty(rid)) {
-
var msg = Message()
-
msg.what = 1
-
msg.obj = rid
-
handler.sendMessage(msg)
-
}
-
}
-
})
-
}
-
fun startForBrowser(tempUrl:String){
-
if(!TextUtils.isEmpty(tempUrl)) {
-
textview3.setOnClickListener(object : View.OnClickListener {
-
override fun onClick(v: View?) {
-
var uri = Uri.parse(tempUrl)
-
var intent = Intent(Intent.ACTION_VIEW, uri)
-
startActivity(intent)
-
}
-
})
-
}
-
}
-
/**
-
* 获取请求链接地址
-
*/
-
fun initPostUrl(rid:String){
-
if(!TextUtils.isEmpty(rid)) {
-
startALaunch(rid, object : OnConnectionCallBack {
-
override fun onBack(string: String) {
-
if (job != null) {
-
job!!.cancel()
-
}
-
var msg = Message()
-
msg.what = 2
-
msg.obj = string
-
handler.sendMessage(msg)
-
}
-
})
-
}
-
}
-
/**
-
* 获取推流地址
-
*/
-
fun initRtmpPullUrl(postUrl:String ){
-
if(!TextUtils.isEmpty(postUrl)) {
-
var room_id = re.findAll(postUrl)
-
room_id.forEach {
-
var msg = Message()
-
msg.what = 3
-
msg.obj = it.value
-
handler.sendMessage(msg)
-
}
-
}
-
}
-
/**
-
* 请求推流地址的接口
-
*/
-
fun getRtmpPullUrl(roomID: String) {
-
if(!TextUtils.isEmpty(roomID)) {
-
OkGo.get<String>("https://webcast-hl.amemv.com/webcast/room/reflow/info/")
-
.params("room_id", roomID)
-
.params("live_id", 1)
-
.execute(object : StringCallback() {
-
override fun onSuccess(response: Response<String>?) {
-
if (response != null) {
-
logged("response:" + response.body())
-
var data =
-
getMap(response.body().toString()).get("data") as Map<String, Any>
-
var room = data.get("room") as Map<String, Any>
-
var stream_url = room.get("stream_url") as Map<String, Any>
-
var rtmp_pull_url = stream_url.get("rtmp_pull_url")
-
var msg = Message()
-
msg.what = 4
-
msg.obj = rtmp_pull_url
-
handler.sendMessage(msg)
-
}
-
}
-
})
-
}
-
}
-
/**
-
* 解析获取推流地址接口返回的数据
-
*/
-
fun getMap(json: String): Map<String, Any> {
-
var map = gson.fromJson<Map<String, Any>>(
-
json,
-
object : TypeToken<Map<String, Any>>() {}.type
-
) as Map<String, Any>
-
return map
-
}
-
/**
-
* 解析成长链接
-
*/
-
fun startALaunch(baseUrl: String, onConnectionCallBack: OnConnectionCallBack) {
-
job = GlobalScope.launch {
-
var con: HttpURLConnection = URL(baseUrl).openConnection() as HttpURLConnection
-
con.instanceFollowRedirects = false
-
con.connectTimeout = 5000
-
val url: String = con.getHeaderField("Location")
-
con.disconnect()
-
onConnectionCallBack.onBack(url)
-
}
-
}
-
interface OnConnectionCallBack {
-
fun onBack(string: String)
-
}
-
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
-
if (keyCode === KeyEvent.KEYCODE_BACK) {
-
val home = Intent(Intent.ACTION_MAIN)
-
home.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
-
home.addCategory(Intent.CATEGORY_HOME)
-
startActivity(home)
-
return true
-
}
-
return super.onKeyDown(keyCode, event)
-
}
-
fun logged(param: String) {
-
Log.d("MyKotlinLog", param)
-
}
-
fun toast(param: String){
-
Toast.makeText(this,param, Toast.LENGTH_SHORT)
-
}
-
}
-
- 布局界面
-
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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"> <EditText android:id="@+id/edittext" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:hint="请粘贴抖音分享链接到这里" /> <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/edittext" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:textColor="#000000" android:textSize="16sp"/> <TextView android:id="@+id/textview3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/textview" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:textIsSelectable="true" android:textColor="#000000" android:textSize="16sp" /> <TextView android:id="@+id/textView4" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:layout_below="@id/textview3" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:textSize="14sp" android:text="(点击链接到浏览器下载视频或长按链接复制在浏览器打开)"/> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/textView4" android:layout_marginTop="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:text="获取下载地址"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="下载过程中请不要关闭浏览器" android:layout_alignParentBottom="true" android:textSize="16sp" android:gravity="center_horizontal"/> </RelativeLayout>
抖音通过分享信息获取,流地址
最新推荐文章于 2024-08-30 18:32:58 发布