前端代码
添加gradle依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
添加访问网络权限
<uses-permission android:name="android.permission.INTERNET" />
允许http 请求请求
android:usesCleartextTraffic="true"
video类
java
package com.example.myapplication;
public class Video {
private String url;
public String getUrl() {
return url;
}
}
VideoService 接口类
java
package com.example.myapplication;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
public interface VideoService {
@GET("/videos")
Call<List<Video>> getVideos();
}
MainActivity 类
java
package com.example.myapplication;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.VideoView;
import android.widget.Toast;
import android.media.MediaPlayer;
import androidx.appcompat.app.AppCompatActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private VideoView videoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView = findViewById(R.id.videoView);
// 初始化 Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.110.148:8080") // 修改为你的 Go 后端地址
.addConverterFactory(GsonConverterFactory.create())
.build();
VideoService service = retrofit.create(VideoService.class);
Call<List<Video>> call = service.getVideos();
showToast("Starting Retrofit call to get videos");
call.enqueue(new Callback<List<Video>>() {
@Override
public void onResponse(Call<List<Video>> call, Response<List<Video>> response) {
if (response.isSuccessful() && response.body() != null) {
List<Video> videos = response.body();
if (!videos.isEmpty()) {
String videoUrl = videos.get(0).getUrl();
showToast("Received video URL: " + videoUrl); // 打印 URL 进行调试
playVideo(videos.get(0).getUrl()); // 播放第一个视频
} else {
showToast("No videos found in the response");
}
} else {
showToast("Failed to fetch videos, Response code: " + response.code());
}
}
@Override
public void onFailure(Call<List<Video>> call, Throwable t) {
showToast("Error fetching videos: " + t.getMessage());
t.printStackTrace();
}
});
}
private void playVideo(String videoUrl) {
showToast("Attempting to play video with URL: " + videoUrl);
String fullUrl = "http://192.168.110.148:8080" + videoUrl; // 完整视频 URL
showToast("Full video URL: " + fullUrl);
Uri videoUri = Uri.parse(fullUrl);
showToast("Parsed URI: " + videoUri.toString());
videoView.setVideoURI(videoUri); // 使用 setVideoURI 方法
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
showToast("Video is prepared, starting playback.");
videoView.start(); // 开始播放
}
});
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
showToast("Error occurred while playing video. What: " + what + ", Extra: " + extra);
return true; // 返回 true 表示我们已经处理了错误
}
});
}
// 用于显示 Toast 信息的辅助方法
private void showToast(String message) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
}
}
go后端代码
Go
package main
import (
"encoding/json"
"net/http"
)
// Video 代表一个视频结构
type Video struct {
URL string `json:"url"`
}
// VideoList 返回的视频列表
var videoList = []Video{
{URL: "/videos/video1.mp4"}, // 本地视频地址
{URL: "/videos/video2.mp4"}, // 本地视频地址 http://192.168.0.104:8080/videos/video2.mp4
}
func main() {
// 在根目录下提供静态文件服务
http.Handle("/videos/", http.StripPrefix("/videos/", http.FileServer(http.Dir("./videos"))))
http.HandleFunc("/videos", getVideos)
http.ListenAndServe(":8080", nil)
}
// getVideos 处理视频请求
func getVideos(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(videoList)
}