int SEQ_IMAGE_INFO = 104;
int SEQ_THUMBNAIL = 105;
int SEQ_FULL_IMAGE = 106;
+
+ int SEQ_START_MOVIE = 107;
+ int SEQ_FINISH_MOVIE = 108;
}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXMessages;
+
+public class FinishRecordingMovie extends FujiXCommandBase
+{
+ private final IFujiXCommandCallback callback;
+ private final byte data0;
+ private final byte data1;
+ private final byte data2;
+ private final byte data3;
+
+ public FinishRecordingMovie(@NonNull IFujiXCommandCallback callback, int startSequenceNumber)
+ {
+ this.callback = callback;
+
+ data0 = ((byte) (0x000000ff & startSequenceNumber));
+ data1 = ((byte)((0x0000ff00 & startSequenceNumber) >> 8));
+ data2 = ((byte)((0x00ff0000 & startSequenceNumber) >> 16));
+ data3 = ((byte)((0xff000000 & startSequenceNumber) >> 24));
+ }
+
+ @Override
+ public IFujiXCommandCallback responseCallback()
+ {
+ return (callback);
+ }
+
+ @Override
+ public int getId()
+ {
+ return (IFujiXMessages.SEQ_FINISH_MOVIE);
+ }
+
+ @Override
+ public byte[] commandBody()
+ {
+ return (new byte[] {
+ // message_header.index : uint16 (0: terminate, 2: two_part_message, 1: other)
+ (byte)0x01, (byte)0x00,
+
+ // message_header.type : stop_recording_movie (0x9021)
+ (byte)0x21, (byte)0x90,
+
+ // sequence number
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+ // data...
+ data0, data1, data2, data3,
+ });
+ }
+}
--- /dev/null
+package net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandCallback;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXMessages;
+
+public class StartRecordingMovie extends FujiXCommandBase
+{
+ private final IFujiXCommandCallback callback;
+
+ public StartRecordingMovie(@NonNull IFujiXCommandCallback callback)
+ {
+ this.callback = callback;
+ }
+
+ @Override
+ public IFujiXCommandCallback responseCallback()
+ {
+ return (callback);
+ }
+
+ @Override
+ public int getId()
+ {
+ return (IFujiXMessages.SEQ_START_MOVIE);
+ }
+
+ @Override
+ public byte[] commandBody()
+ {
+ return (new byte[] {
+ // message_header.index : uint16 (0: terminate, 2: two_part_message, 1: other)
+ (byte)0x01, (byte)0x00,
+
+ // message_header.type : start_movie_recording (0x9020)
+ (byte)0x20, (byte)0x90,
+
+ // sequence number
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+ // data
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+
+ });
+ }
+}
setFujiXKeyPanelClickListener(view, R.id.button_fuji_x_xv_plus);
setFujiXKeyPanelClickListener(view, R.id.button_fuji_x_flash);
setFujiXKeyPanelClickListener(view, R.id.button_fuji_x_timer);
+ setFujiXKeyPanelClickListener(view, R.id.button_fuji_x_video_on_off);
connectStatus = view.findViewById(R.id.connect_disconnect_button);
if (connectStatus != null)
import android.os.Vibrator;
import android.util.Log;
import android.view.View;
+import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
+import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import net.osdn.gokigen.gr2control.R;
import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandCallback;
import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.IFujiXCommandPublisher;
import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.CommandGeneric;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.FinishRecordingMovie;
import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.IFujiXCameraCommands;
+import net.osdn.gokigen.gr2control.camera.fuji_x.wrapper.command.messages.StartRecordingMovie;
import net.osdn.gokigen.gr2control.camera.utils.SimpleLogDumper;
import java.util.List;
private static final boolean isDumpLog = false;
private final IInterfaceProvider interfaceProvider;
private final Vibrator vibrator;
+ private boolean isRecordingVideoMovie = false;
+ private boolean commandIssued = false;
+ private int startMovieSequenceNumber = 0;
LiveViewFujiXKeyPanelClickListener(@NonNull FragmentActivity activity, @NonNull IInterfaceProvider interfaceProvider, @Nullable Vibrator vibrator)
{
updateSelection(ICameraStatus.SELF_TIMER);
isVibrate = false;
break;
-
+ case R.id.button_fuji_x_video_on_off:
+ startFinishMovie();
+ break;
default:
isVibrate = false;
break;
}
/**
+ * ビデオ撮影開始と終了
+ *
+ */
+ private void startFinishMovie()
+ {
+ try
+ {
+ if (commandIssued)
+ {
+ // すでにコマンド発行中。コマンドの発行は抑止する
+ Log.v(TAG, " COMMAND IS ALREADY ISSUED...");
+ return;
+ }
+ commandIssued = true;
+
+ IFujiXCommandPublisher publisher = interfaceProvider.getFujiXInterfaceProvider().getCommandPublisher();
+ if (isRecordingVideoMovie)
+ {
+ // 撮影中の場合には、撮影を止める
+ publisher.enqueueCommand(new FinishRecordingMovie(new IFujiXCommandCallback() {
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ commandIssued = false;
+ isRecordingVideoMovie = false;
+ updateMovieRecordingIcon();
+ SimpleLogDumper.dump_bytes(" STOP MOVIE REPLY (" + startMovieSequenceNumber + ") ", rx_body);
+ startMovieSequenceNumber = 0;
+ }
+
+ @Override
+ public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
+ {
+ // 何もしない
+ }
+
+ @Override
+ public boolean isReceiveMulti()
+ {
+ return (false);
+ }
+ }, startMovieSequenceNumber));
+ }
+ else
+ {
+ // 撮影を開始する
+ publisher.enqueueCommand(new StartRecordingMovie(new IFujiXCommandCallback() {
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ commandIssued = false;
+ if ((rx_body[7] == (byte) 0x20)&&(rx_body[6] == (byte) 0x01))
+ {
+ // 応答コード OKの場合... SequenceNumberを記憶する
+ startMovieSequenceNumber = ((((int) rx_body[11]) & 0xff) << 24) + ((((int) rx_body[10]) & 0xff) << 16) + ((((int) rx_body[9]) & 0xff) << 8) + (((int) rx_body[8]) & 0xff);
+ isRecordingVideoMovie = true;
+ }
+ updateMovieRecordingIcon();
+ SimpleLogDumper.dump_bytes(" START MOVIE REPLY (" + startMovieSequenceNumber + ") ", rx_body);
+ }
+
+ @Override
+ public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
+ {
+ // 何もしない
+ }
+
+ @Override
+ public boolean isReceiveMulti()
+ {
+ return (false);
+ }
+ }));
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ commandIssued = false;
+ }
+ }
+
+ private void updateMovieRecordingIcon()
+ {
+ try
+ {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ImageView imageView = activity.findViewById(R.id.button_fuji_x_video_on_off);
+ if (isRecordingVideoMovie)
+ {
+ //imageView.setImageDrawable(ContextCompat.getDrawable(activity,R.drawable.ic_videocam_off_black_24dp));
+ imageView.setImageDrawable(ContextCompat.getDrawable(activity,R.drawable.ic_stop_black_24dp));
+ }
+ else
+ {
+ imageView.setImageDrawable(ContextCompat.getDrawable(activity,R.drawable.ic_videocam_black__24dp));
+ }
+ imageView.invalidate();
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+
+
+
+ /**
* ぶるぶるさせる
*
*/
--- /dev/null
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M6,6h12v12H6z"/>
+</vector>
--- /dev/null
+<vector android:height="24dp" android:tint="#121212"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FF000000" android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
+</vector>
--- /dev/null
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M21,6.5l-4,4V7c0,-0.55 -0.45,-1 -1,-1H9.82L21,17.18V6.5zM3.27,2L2,3.27 4.73,6H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.21,0 0.39,-0.08 0.54,-0.18L19.73,21 21,19.73 3.27,2z"/>
+</vector>
android:gravity="center" />
<ImageView
- android:id="@+id/button_fuji_x_dummy"
- android:layout_width="34pt"
- android:layout_height="9pt"
- android:layout_below="@id/label_fuji_x_xv_center"
- android:layout_alignLeft="@id/label_fuji_x_xv_center"
- android:layout_alignStart="@id/label_fuji_x_xv_center"
+ android:id="@+id/button_fuji_x_video_on_off"
+ android:layout_width="20pt"
+ android:layout_height="14pt"
+ android:layout_below="@id/button_fuji_x_xv_minus"
+ android:layout_alignLeft="@id/button_fuji_x_xv_minus"
+ android:layout_alignStart="@id/button_fuji_x_xv_minus"
android:scaleType="fitCenter"
- android:visibility="invisible"
+ android:visibility="visible"
android:clickable="true"
android:focusable="true"
- android:src="@drawable/ic_camera_roll_black_24dp"
+ android:src="@drawable/ic_videocam_black__24dp"
android:layout_marginTop="6pt"
android:gravity="center" />
android:id="@+id/button_fuji_x_flash"
android:layout_width="20pt"
android:layout_height="14pt"
- android:layout_below="@id/button_fuji_x_dummy"
+ android:layout_below="@id/button_fuji_x_video_on_off"
android:layout_alignLeft="@id/button_fuji_x_tv_minus"
android:layout_alignStart="@id/button_fuji_x_tv_minus"
android:scaleType="fitCenter"
android:id="@+id/button_fuji_x_timer"
android:layout_width="34pt"
android:layout_height="14pt"
- android:layout_below="@id/button_fuji_x_dummy"
- android:layout_alignLeft="@id/button_fuji_x_dummy"
- android:layout_alignStart="@id/button_fuji_x_dummy"
+ android:layout_below="@id/button_fuji_x_video_on_off"
+ android:layout_alignLeft="@id/label_fuji_x_xv_center"
+ android:layout_alignStart="@id/label_fuji_x_xv_center"
android:scaleType="fitCenter"
android:visibility="visible"
android:clickable="true"
android:gravity="center" />
<ImageView
- android:id="@+id/button_fuji_x_dummy"
- android:layout_width="34pt"
- android:layout_height="9pt"
- android:layout_below="@id/label_fuji_x_xv_center"
- android:layout_alignLeft="@id/label_fuji_x_xv_center"
- android:layout_alignStart="@id/label_fuji_x_xv_center"
+ android:id="@+id/button_fuji_x_video_on_off"
+ android:layout_width="20pt"
+ android:layout_height="14pt"
+ android:layout_below="@id/button_fuji_x_xv_minus"
+ android:layout_alignLeft="@id/button_fuji_x_xv_minus"
+ android:layout_alignStart="@id/button_fuji_x_xv_minus"
android:scaleType="fitCenter"
- android:visibility="invisible"
+ android:visibility="visible"
android:clickable="true"
android:focusable="true"
- android:src="@drawable/ic_camera_roll_black_24dp"
+ android:src="@drawable/ic_videocam_black__24dp"
android:layout_marginTop="6pt"
android:gravity="center" />
android:id="@+id/button_fuji_x_flash"
android:layout_width="20pt"
android:layout_height="14pt"
- android:layout_below="@id/button_fuji_x_dummy"
+ android:layout_below="@id/button_fuji_x_video_on_off"
android:layout_alignLeft="@id/button_fuji_x_tv_minus"
android:layout_alignStart="@id/button_fuji_x_tv_minus"
android:scaleType="fitCenter"
android:id="@+id/button_fuji_x_timer"
android:layout_width="34pt"
android:layout_height="14pt"
- android:layout_below="@id/button_fuji_x_dummy"
- android:layout_alignLeft="@id/button_fuji_x_dummy"
- android:layout_alignStart="@id/button_fuji_x_dummy"
+ android:layout_below="@id/button_fuji_x_video_on_off"
+ android:layout_alignLeft="@id/label_fuji_x_xv_center"
+ android:layout_alignStart="@id/label_fuji_x_xv_center"
android:scaleType="fitCenter"
android:visibility="visible"
android:clickable="true"