Потоковая передача видео в реальном времени с телефона на телефон с помощью сокета fd

Я новичок в программировании на Android и застрял. Я исследовал различные способы потоковой передачи видео в реальном времени с телефона на телефон и похоже, что он в основном функциональный, за исключением, конечно, самой важной части: воспроизведения потока. Похоже, что поток отправляется с одного телефона, но второй телефон не может воспроизвести поток.

Вот код для стороны воспроизведения

public class VideoPlayback extends Activity implements Callback {
MediaPlayer mp;
private SurfaceView mPreview;
private SurfaceHolder holder;
private TextView mTextview;
public static final int SERVERPORT = 6775;
public static String SERVERIP="192.168.1.126";
Socket clientSocket;
private Handler handler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mPreview = (SurfaceView) findViewById(R.id.surfaceView1);
    mTextview = (TextView) findViewById(R.id.textView1);
    holder = mPreview.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    mTextview.setText("Attempting to connect");
    mp = new MediaPlayer();
    Thread t = new Thread(){
        public void run(){
            try {
                    clientSocket = new Socket(SERVERIP,SERVERPORT);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        mTextview.setText("Connected to server");
                    }
                });
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(clientSocket);
                            pfd.getFileDescriptor().sync();
                            mp.setDataSource(pfd.getFileDescriptor());
                            pfd.close();
                            mp.setDisplay(holder);
                            mp.prepareAsync();
                            mp.start();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                    }
                });

            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };
    t.start();
}

А вот код для стороны потоковой передачи

public class VideoStreaming extends Activity{
// User Interface Elements
VideoView mView;
TextView connectionStatus;
SurfaceHolder mHolder;
// Video variable
MediaRecorder recorder; 
// Networking variables
public static String SERVERIP="";
public static final int SERVERPORT = 6775;
private Handler handler = new Handler();
private ServerSocket serverSocket;  
/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // Define UI elements
    mView = (VideoView) findViewById(R.id.video_preview);
    connectionStatus = (TextView) findViewById(R.id.connection_status_textview);
    mHolder = mView.getHolder();
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    SERVERIP = "192.168.1.126";
    // Run new thread to handle socket communications
    Thread sendVideo = new Thread(new SendVideoThread());
    sendVideo.start();
}
 public class SendVideoThread implements Runnable{
    public void run(){
        // From Server.java
        try {
            if(SERVERIP!=null){
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        connectionStatus.setText("Listening on IP: " + SERVERIP);
                    }
                });
                serverSocket = new ServerSocket(SERVERPORT);
                while(true) {
                    //listen for incoming clients
                    Socket client = serverSocket.accept();
                    handler.post(new Runnable(){
                        @Override
                        public void run(){
                            connectionStatus.setText("Connected.");
                        }
                    });
                    try{
                            // Begin video communication
                            final ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(client);
                            handler.post(new Runnable(){
                                @Override
                                public void run(){
                                    recorder = new MediaRecorder();
                                    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                                    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);                 
                                    recorder.setOutputFile(pfd.getFileDescriptor());
                                    recorder.setVideoFrameRate(20);
                                    recorder.setVideoSize(176,144);
                                    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
                                    recorder.setPreviewDisplay(mHolder.getSurface());
                                    try {
                                        recorder.prepare();
                                    } catch (IllegalStateException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    } catch (IOException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    }
                                    recorder.start();
                                }
                            });
                    } catch (Exception e) {
                        handler.post(new Runnable(){
                            @Override
                            public void run(){
                                connectionStatus.setText("Oops.Connection interrupted. Please reconnect your phones.");
                            }
                        });
                        e.printStackTrace();
                    }
                }
            } else {
                handler.post(new Runnable() {
                    @Override
                    public void run(){
                        connectionStatus.setText("Couldn't detect internet connection.");
                    }
                });
            }
        } catch (Exception e){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    connectionStatus.setText("Error");
                }
            });
            e.printStackTrace();
        }
        // End from server.java
    }
}

I при попытке создать MediaPLayer

05-24 16:25:39.360: ERROR/MediaPlayerService(88): offset error
05-24 16:25:39.360: ERROR/MediaPlayer(11895): Unable to to create media player
05-24 16:25:39.360: WARN/System.err(11895): java.io.IOException: setDataSourceFD failed.: status=0x80000000
05-24 16:25:39.360: WARN/System.err(11895):     at android.media.MediaPlayer.setDataSource(Native Method)
05-24 16:25:39.360: WARN/System.err(11895):     at android.media.MediaPlayer.setDataSource(MediaPlayer.java:811)
05-24 16:25:39.360: WARN/System.err(11895):     at com.conti.VideoPlayBack.VideoPlayback$1$2.run(VideoPlayback.java:63)
05-24 16:25:39.360: WARN/System.err(11895):     at android.os.Handler.handleCallback(Handler.java:587)
05-24 16:25:39.360: WARN/System.err(11895):     at android.os.Handler.dispatchMessage(Handler.java:92)
05-24 16:25:39.360: WARN/System.err(11895):     at android.os.Looper.loop(Looper.java:132)
05-24 16:25:39.360: WARN/System.err(11895):     at android.app.ActivityThread.main(ActivityThread.java:4025)
05-24 16:25:39.360: WARN/System.err(11895):     at java.lang.reflect.Method.invokeNative(Native Method)
05-24 16:25:39.360: WARN/System.err(11895):     at java.lang.reflect.Method.invoke(Method.java:491)
05-24 16:25:39.360: WARN/System.err(11895):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
05-24 16:25:39.360: WARN/System.err(11895):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
05-24 16:25:39.360: WARN/System.err(11895):     at dalvik.system.NativeStart.main(Native Method)

появляется следующая ошибка. Есть ли у кого-нибудь исправление для этого? Заранее благодарим!

24
задан udm_coder 24 May 2011 в 21:05
поделиться

2 ответа

Я нашел проект с открытым исходным кодом для реализации того, что я пытался. Он обрабатывает видео с метаданными через IP-камеру. Хотя он не отправляет видео непосредственно на телефон, он транслирует видео на различные устройства для просмотра. Исходный код можно найти на следующей странице проекта http://code.google.com/p/ipcamera-for-android/ .

В Android 4.4 есть еще один способ воспроизведения живого потока MJPEG. Воспроизводимый поток должен транслироваться другим устройством через порт по UDP. Допустим, у нас есть трансляция потока 192.168.0.101:8080. Мы можем воспроизвести поток, добавив WebView к нашему макету. Затем в нашей деятельности мы делаем следующее:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mjpeg_activity);
    // Grab instance of WebView
    WebView webView = (WebView)findViewById(R.id.webViewStream);
    // Set page content for webview
    webView.loadData("<html><head><meta name='viewport' content='target-densitydpi=device-dpi,initial-scale=1,minimum-scale=1,user-scalable=yes'/></head><body><center><img src=\"http://192.168.0.101:8080/\" alt=\"Stream\" align=\"middle\"></center></body></html>", "text/html", null);
    webView.getSettings().setBuiltInZoomControls(true);
}

В контенте мы говорим веб-странице использовать dpi устройства. Чтобы помочь пользователю увеличить масштаб на веб-странице, я добавил следующий начальный масштаб = 1, минимальный масштаб = 1, масштабируемый пользователем = да. Изначально изображение имеет оригинальный размер и не может быть меньше. Теперь пользователь может масштабировать, чтобы увеличить изображение и уменьшить его до исходного размера. Удаление минимального масштаба даст пользователю полный контроль над масштабированием, но может привести к тому, что изображение станет настолько маленьким, что вы не сможете его найти.

6
ответ дан 29 November 2019 в 00:28
поделиться

Необходимо установить выходной формат рекордера 8 (MPEG-2TS, доступен только для Android версии 3.0+). В этом случае запишите видео в этом формате и отправьте поток на другой телефон и сохраните его в файл. И воспроизведите его после записи некоторых данных в файл, после чего вы сможете увидеть прямую трансляцию.

Примечание. Невозможно напрямую воспроизвести дескриптор файла сокета, поскольку сокет fd недоступен для поиска. Если вы используете сокет fd, вы получите «ошибку смещения». Запись возможна, но игра ограничена.

4
ответ дан 29 November 2019 в 00:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: