Потоковое видео с телефона на телефон с помощью сокета FD - PullRequest
24 голосов
/ 25 мая 2011

Я новичок в программировании 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
    }
}

При попытке создать 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)

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

Ответы [ 4 ]

6 голосов
/ 10 июня 2011

Я нашел проект с открытым исходным кодом для реализации того, что я пытался.Он обрабатывает видео с метаданными через 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, масштабируемый пользователем = да.Изначально изображение имеет оригинальный размер и не может быть меньше.Теперь пользователь может масштабировать, чтобы увеличить изображение и уменьшить его до исходного размера.Удаление минимального масштаба предоставит пользователю полный контроль над масштабированием, но может привести к тому, что изображение станет настолько маленьким, что вы не сможете его найти.

4 голосов
/ 21 апреля 2012

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

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

0 голосов
/ 17 июля 2014

Скачать исходный код с: http://code.google.com/p/ipcamera-for-android/ (https://github.com/Teaonly/android-eye)

Сначала соберите jni (используйте ndk-build с cygwin)

Я мог бы успешно построить этот проект

0 голосов
/ 25 мая 2011

Взгляните на Потоковая передача на Android MediaPlayer , где могут быть полезные советы о том, как выполнять потоковую передачу. Я подозреваю, что проблема в том, что Android пытается найти файл, но, будучи сетевым сокетом, не может. Может быть, какой-нибудь буфер диска / памяти, который поддерживает поиск, может помочь?

...