Subscribe via RSS
29Apr/202

Amiga 500 – External IDE Port

After building an internal IDE port for the Amiga 500, it was time to try an external port that connects to the expansion slot. This happened to be another lesson in taking-your-time-and-doing-proper-research. As I was unpacking the bags for this unit, I realised I'd bought SMD resistors and capacitors that were, literally, microscopic. I couldn't even see them in the tape-strips that they were sent on.

DSC00242

I went back to the bill of materials as linked to on the project page and realised that there was a code after the SMD items: 0805. Turns out there's an industry standard sizing and I had no idea. I therefore put in a new order to DigiKey and got these correct, got the relays correct (for another project) and then got a few other handy bits. Here's a photo of the size comparison, only take-able once I'd received the second order. Actually, I must admit that DigiKey's free shipping with any order over 50 bucks is super fast!

Now that I had the right items, I whipped out the boards that I'd had printed and started placing the chips.

DSC00170

The replacement items arrived and I started assembling the boards. It wasn't until I tried to actually solder in the 74HC04 inverter that I realised I'd also ordered the wrong part. SMD chips come in a plethora of sizings, just like the resistor component sizing above and I'd purchased SOP14s instead of SOIC14s. I decided to MacGyver it and make them fit... but it caused me high levels of stress as things didn't go smoothly during the testing phase.

DSC00174 DSC00177 DSC00180

After ruining around 4 boards, I managed to finally solder down the 4 ICs. This was my first attempt at SMD soldering and I must say that I'm not a fan. Firstly, I had the wrong-sized solder, but I fixed that up by purchasing the smallest available: 0.7mm. With this new solder, it was much easier to not bridge legs on the ICs, but the tip on my soldering iron was also too large. I've since ordered smaller 'blade' style tips.

DSC00182 DSC00185 DSC00194

You can see above where I managed to solder the ill-fitting inverter upside down... I then tried to remove it and trashed the traces on the board. So damn fiddly... And then the resistors and capacitors... the best method I found was to tin one pad, use fine tweezers to place the component on the tinned pad and then melt it in place... from there, you can just solder up the other side. I then tested all continuity to make sure contact was correctly made.

DSC00189

The edge connector wasn't a simple solder-in-position... I had options. I could solder in a right-angled header and then build a bridging board, as per the original author's instructions. Or I could use a single vertical pin header and bend the bottom row of pins of the edge connector and solder it all together. This latter option lead to a much stronger build, so I went with it.

DSC00203 DSC00205 DSC00209

DSC00211

DSC00214 DSC00222 DSC00224

Finally, I just needed the IDE pin-header in place!

DSC00238

After around 10 hours of debugging, I managed to get this thing to work. Firstly, one or two legs on the inverter IC weren't cleanly making contact, and then I realised I'd put the LED on the wrong way around. After a lot of further tracing with a multimeter, it turns out that my master HDD was on cable-select when it needed to be forced. I also seemed to require a second HDD as slave to get HDToolBox to read the drives correctly.

DSC00241 DSC00244 DSC00245

But it works! I'll write up a post very shortly on how to work with these drives. For now, you can use the boot disks from my other internal IDE port post.

Filed under: C64/Amiga 2 Comments
25Apr/200

PCMCIA Cards on Desktop PCs

The PCMCIA (or PC Card) standard was built for portable machines which involve smaller form-factors than desktop PCs. Similar to ISA and PCI cards in desktop PCs, the cards offered expansion capabilities for portable machines including storage and communications. The most common cards are either ethernet, modem or wireless. Storage became an option with both flash memory cards, IDE interface cards and SCSI cards.

Desktop machines can be fitted out with PCMCIA card interfaces. Below I'll cover ISA to PCMCIA, PCI to PCMCIA and USB to PCMCIA, noting the limitations of each. I've had an IBM External CD-ROM 0991-011 in the collection for a while and I'd always wanted to check out its capabilities noting that it has a sound-card built-in!

The desktop machine that'll be running the tests is a PIII-500 with 512mb RAM. It's got enough storage internally to support multiple versions of Windows, so we can test compatibility across the board. I've actually taken out ethernet and sound cards, and disabled unnecessary onboard peripherals, to prevent hardware conflicts with any installed PCMCIA bridge.

PCMCIA Cards

I've tested the following PCMCIA Cards during this article. I wanted to make sure I had a card from each category, since I'd expected that certain adapters wouldn't handle all types of cards.

Device Description Driver
SanDisk 1.2gb Memory Card Flash Storage Uses the standard Mass Storage Driver
Belkin 11g Wireless Card Wireless Network Download
IBM External CD-ROM + Sound Card + Gameport External IDE Interface + Extra Download.EXE

I'm pretty much in-love with the IBM External CD. It's got the beautiful 'Aptiva'-esque styling and a bloody sound-card built-in!

DSC00135

DSC00137 DSC00140 DSC00143

Yup, that's the amazing all-inclusive IBM External CD-ROM, but we'll discuss its capabilities at a later date. Following are the two boring (aka. just-work!) cards...

DSC00149

Super boring. They didn't even try to use a differing palette!

PCMCIA Interfaces

To slap a PCMCIA card into a desktop machine, you'll need some kind of adapter. The following are the units that have been tested throughout this article.

Device Connection
IO-Data CardDock EX/DV ISA
Ricoh PCI
Ricoh PCI
Condor PCI Super Card PCI
AirFree USB

First up, here's the Condor PCI Super Card. It's huge and seems to have been custom built for a specific chassis? It might actually have been for a Kodak photo kiosk or somesuch where there are card slots on the front of the case. Based on it's length, I could see this card providing ports to the front.

DSC00094

Unfortunately, it wasn't detected by any part of the system!

DSC00095 DSC00098 DSC00099

The other Ricoh 485-based and 475II-based cards...

DSC00105 DSC00107 DSC00111

Hagiwara Sys-Com Airfree

DSC00114

DSC00116 DSC00117 DSC01195

And I-O DATA's CardDock2-EX/DV...

DSC00121

DSC00127 DSC00131 DSC00132

The results are as follows. The basic finding have been that the newer PCI/USB interfaces only support specific classes of PCMCIA devices. Those being Mass Storage and Network. As soon as you bring in a card that needs interrupts or other low I/O ranges then you're out of luck. On the flip-side, newer versions of windows don't support the older ISA hardware, meaning that the ISA PCMCIA bridge that I had just wont work on anything newer than Millenium.

Bridge Device Operating System Result
IO-Data CardDock EX/DV All Windows 98 SE Fully operational.
IO-Data CardDock EX/DV Any Windows XP Card cannot be installed. Drivers wont recognise hardware and Add/Remove Hardware doesn't auto-detect it.
Ricoh 485/475II Sandisk Flash Storage Windows 98 SE Works, but cannot be easily re-partitioned. Needed to use BOOTICE. (see information below)
Ricoh 485/475II Belkin 11g Wireless Card Windows 98 SE Worked perfectly. Used Odyssey Client 4.52 for WPA2 access.
Ricoh 485/475II IBM External CDROM Any Failed with resource issues. Hardware could not start.
Condor Super PCI Any Any Entire card couldn't be recognised. Even the BIOS didn't list it. Going in the bin... but it's so cool-looking!
Hagiwara Sys-com Airfree Flash Storage Windows 98 SE Works fine. A bit tricky to install on the US English version of Windows 98 SE as the installer just drops out. Works perfectly on Windows 98 SE JP.
Hagiwara Sys-com Airfree Belkin 11g Wireless Windows XP Works fine, as above with installation.
Hagiwara Sys-com Airfree IBM External CDROM Any As above with the PCI cards, it just doesn't work at all thanks to resource limitations.

Partitioning Removable Media In Windows XP Or Lower

I'd somehow managed to trash the partition table on the SanDisk Flash Memory during the testing above. It hadn't caused the resource errors above (I went back and re-tested the scenarios after I'd realised the disk wasn't actually readable), but it had caused errors when trying to access the drive in My Computer... when it actually chose to show up. Both FDISK, DISKPART and Disk Management in all forms/versions/flavours of old-windows didn't want to touch the partition table. I also tried Partition Magic 7.0, but that didn't care either.

winxp-diskpart-nope winxp-pm70-cant-see winxp-sandisk

Actually, FDisk in Windows 98 SE JP managed to show the card, but then suggested that it was onlt 136mb in size? I actually tried to follow through with it and that's what probably really killed the partition table.

sandisk-fdisk-1 sandisk-fdisk-3 sandisk-fdisk-2

Thanks to this post at lancelhoff.com, I was directed to an older version of BOOTICE which disregards all forms of safety and allows you to totally wipe and re-partition removable media in older versions of Windows.

winxp-bootice-2

Choose the correct disk and click 'Parts Manage'. You'll be presented with the screen below...

winxp-bootice-success

I was expecting an option to set up the actual parition table, but nothing was presented. Instead you need to choose 'ReFormat USB Disk' and choose the top option.

WPA2 on Windows 98 SE

As mentioned above, you can install the Odyssey Client 4.52 on Windows 98 to enable connections to WPA2-encrypted wireless networks.

yellow-ricoh-installed-with-wifi-wpa2

I expected that I'd have to build a guest network with WEP encryption, or worse - no encryption, to test the wireless PCMCIA cards... but I didn't! This software worked perfectly!

Conclusion

The IBM External CD-ROM is super-cool! The fact that it comes with a sound card inbuilt and a gameport/midiport is awesome. I suppose it's really suited to an older laptop that doesn't have a soundcard. I actually tried using the joystick port and it works fine, but don't expect all joysticks to work 100%. I'll post about that soon.

As for the PCMCIA to PCI or USB, you're mileage may vary. If you just want to use flash storage or ethernet cards, then go for it... but why not just get an ISA or PCI card? I remember back in the day I really wanted a PCMCIA to PCI adapter for a wireless card to join the Canberra Wireless network... as actual PCI wireless cards were still a pipe-dream. That never happened... and now I have a surplus of the technology and no real reason to need it. Actually... that's the point behind too many posts on this blog!

Filed under: Retro No Comments
14Apr/202

Passing Freight in South Yarra – April, 2020

Thanks to having a camera hanging off the balcony, I'm able to capture and record scenes like the following. Also, thanks to FTTP NBN, the steam is live 24/7.

Above you'll find an up Maryvale Paper Service entering first from the left. Shortly after, a down Long Island Steel train will pass through. The up service was relatively on-time, but the steel was allocated a run for the 11:30am service, running well-late even for the 13:30 (9557) timeslot.

Anyway, here's the live cam. (But if below is temporarily unavailable, browse here to find the latest URL: stevenhoefel - youtube - live)

Enjoy!

Filed under: AUS 2 Comments
8Apr/200

Restoring an Azure DB Bacpac into SQL Express

Every so-often, one receives a request out of the blue to revive things that one has totally forgotten about. In most cases, it's comments on pages on this hideous blog asking questions about things that I've gotten rid of, in one form or another, and can't answer! Fortuantely, this time I could: it was a request to revive a project which had been on ice for a long time, but had been well-backed-up... or so I thought.

Firstly, it took me two days to find the files... not cool. If you shut down a project, get EVERYTHING and put it in ONE LOCATION. The system comprised of a zip of the IIS inetpub folder, a zip of the data drive and finally, a database backup from the SQL-as-a-service database. This, thanks to Azure not providing direct access to the server, takes the form of a bacpac file.

Back in the day, when developing, the preprod server was located on a HP something-something with 44gb of RAM which hosted multiple VMs. It made a fantastic noise when it first booted, making sure the fans could hit the required RPMs, and so it was left on most of the time. It was quite the powerhouse and did everything we needed. To save cost, the preprod server only ran SQL Express, so whenever we needed to back-port the production database to diagnose and squash bugs, we needed to manipulate the backups to make them fit.

What do I mean by this? Well SQL Express (or, at least the old 2014 version running in the VM) isn't as capable as Azure DBs and therefore you needed modify the backups so that they wouldn't throw errors when they were being restored. Below is a perfect example (this happened tonight) of such errors...

database-1 database-2 database-3

All looking OK, taking large amounts of time, and then...

database-4

Bang! With is not a valid operator... what's it doing embedded in a SQL script? Let's find out! Did you know that a bacpac file is just a pkzip archive? Install 7-zip, right click on the bacpac file and choose Open Archive.

database-5

Nice, contents. You'll find the database tables stored as BCP files in the Data folder and actual entire structure and scripts in the model.xml file. If you have your favourite editor installed correctly, then you should just be able to double-click model.xml and edit the file inline.

We know that the error is about shared access keys, so I CTRL-F'd the relevant keyword and the result was at the very bottom of the file. It's trying to store the logging and auditing on Azure shared storage... which is obviously not a good idea if we're running a private server. It's also totally incompatible with SQL Express, so lets rip it out.

<DataSchemaModel>
	<Model>
		...
		<Element Type="SqlDatabaseCredential" Name="[https://azure.net/sqldbauditlogs]">
			<property Name="Identity" Value="SHARED ACCESS SIGNATURE">
		</Element>
		<Element Type="SqlDatabaseCredential" Name="[https://azure.net/sqldbtdlogs]">
			<Property Name="Identity" Value="SHARED ACCESS SIGNATURE" />
		</Element>
		<Element Type="SqlFullTextCatalog" Name="[SnomedCatalog]">
			<Property Name="IsAccentSensitive" Value="True" />
			<Relationship Name="Authorizer">
				<Entry>
					<References ExternalSource="BuiltIns" Name="[dbo]" />
				</Entry>
			</Relationship>
		</Element>
	</Model>
</DataSchemaModel>

I also ripped out the Full-Text Searching block above, as shown, and another block much further above that was also referencing this block. Once I'd made all the changes to the zip file, I closed my editor and went back to 7-zip.

database-6

Yes, 7-zip, I very muchly would love to commit the changes back into this 1gb archive, thank you. From here, I attempted to deploy the bacpac to the server...

Ok, right, by editing a file inside this archive, we've trashed the thumbprint. A checksum is a magical calculation of a chunk of binary data that, somehow, resolves it down to a unique number that indicates the bits. If a bit changes, the checksum number changes and this allows software to know if things have been tampered with. That's what has occurred here... we've actually tampered with it and it's changed the calculation.

The SQL Server has run a calculation on the file and the result has mismatched with something, but with what? Turns out that in the original.xml file is a checksum value! We need to change this value to the new checksum, but how do we calculate that? Don't even bother thinking, just copy the following script into a file called checksum.ps1 and store it in your home directory.

$modelXmlPath = Read-Host "model.xml file path"
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create("System.Security.Cryptography.SHA256CryptoServiceProvider")
$fileStream = new-object System.IO.FileStream ` -ArgumentList @($modelXmlPath, [System.IO.FileMode]::Open)
$hash = $hasher.ComputeHash($fileStream)
$hashString = ""
Foreach ($b in $hash) { $hashString += $b.ToString("X2") }
$fileStream.Close()
$hashString

If you've never run scripts in Powershell before, then you'll need to run the following command first if you get an error like 'checksum.ps1 cannot be loaded because running scripts is disabled on this system.'

set-executionpolicy remotesigned

Once sorted, run the following:

PS D:\> checksum.ps1
model.xml file path: d:\model.xml
898D9323A53F0C52B782867B9E8343D8371059A1192849F793CEA168FEAC7AA0

That final number needs to be pasted into original.xml in the archive. Save it back into the archive and deploy once more. Note that, before you try to deploy again, you'll need to detach the half-deployed database and delete the mdf/ldf files that were half-stored in the deployment folders that you set when you tried previously.

I then hit another error, a long way into deployment where the server said that AT was a shit command. Turns out one of my previous developers had tried to cast a datetime into a timezone using the query getdate() AT TIME ZONE 'UTC' AT TIME ZONE 'Aus Eastern Standard Time'. Neat! But SQL Express hates that... so... open the archive, edit model.xml, save it, copy it out of the archive, checksum it, edit original.xml and deploy again...

database-7

Fiinnnnaaalllyyyy....!!! IT'S ALIVE! ... Hah... it's not...

database-8

dbo.Sort Failed? What dat? Google! There's always someone else that has had your error before... tempdb full? Let's add a new 100gb disk and slap tempdb over there. You can do this by running the following in a new query editor against master...

USE master;
GO

ALTER DATABASE tempdb 
MODIFY FILE (NAME = tempdev, FILENAME = 'T:\MSSQL\DATA\tempdb.mdf');
GO

ALTER DATABASE tempdb 
MODIFY FILE (NAME = templog, FILENAME = 'T:\MSSQL\DATA\templog.ldf');
GO

And you'll need to restart SQL before it applies...

The file "tempdev" has been modified in the system catalog. The new path will be used the next time the database is started.
The file "templog" has been modified in the system catalog. The new path will be used the next time the database is started.

Completion time: 2020-04-08T22:55:04.1929547+10:00

Of course, you'll need to change T drive to something else! Enjoy!... or not... what the hell is this error?

database-9

Right, memory? Is that physical memory? Swapfile memory? Or storage space? Fortunately, it's a VM, so lets increase every one of those. If you have the RAM, then that's easy... slide that slider to the right. Disk space is a little trickier. Open the main Virtual Box console and choose Virtual Media Manager from the File menu. From here, select your disks, slide the slider to the right and then hit apply. Note that this will only change the dimensions of the disk, it wont touch the partitions.

database-10 database-11 database-12

So, to extend the partitions, open Disk Management (right-click the start button) and then find the drive. Once located, right-click and choose Extend Volume. If the free space is directly after the drive, it'll already be selected and you can just hit nekk-nekk-finish. Enjoy!

Filed under: Retro No Comments
7Apr/200

Mixing And Matching KVM Cables

Thanks to these new working-from-home shennanigans, I had to dig through the to-sell-at-trash-and-treasure box and find a KVM Switch to hook up all my machines. The desk used to only have one PC, but now additionally houses my work laptop and a large development server. I've got two monitors, and I want one of those to switch over to the development PC when required. I also want my keyboard and mouse to switch between all devices. To do this, I'll use the VGA/USB KVM to channel input and video to the monitor.

DSC00016

The best KVM in the box'o'stuff was a Belkin SOHO 4-port VGA+USB+Audio switch. Fortunately it had two of the KVM cables, so I could switch in my Laptop and development machine... but... I had to then unplug the USB to switch the input to the main PC. This wasn't optimal, so I went digging in the box again for another cable. The Belkin cables switched both Audio in+out, VGA and USB. From the outside, it looked like the audio channels were external to the VGA cable, unlike the USB which does seem to run through the same wires.

Back into the box, but unfortunately there were no other Belkin-branded cables. What I did find was another KVM with USB switching: Level One 2-Port VGA+USB KVM Switch.

DSC00033

DSC00013

This one also switched audio, but via USB instead of standard audio jacks. I grabbed a cable from it and was about to just plug everything together, but then I halted. USB has four wires, with two of those being the 5v rails. If there's any wiring differences between the switches then I could well send voltages in haphazard directions and cook equipment!

USB over VGA cable pinout

Wanting to hook this all together, I reached for my multimeter and started mapping out both the Level One and Belkin KVM cables. Thankfully, they have used very similar wiring for their cables! Thanks to monitors now talking digitally to hosts when describing their capabilities, there are spare pins on the cables to use for other purposes. There's a lot of extra ground pins also, but Belkin still preferred to keep those split whilst Level One happily merged them altogether.

DSC00019

Pin VGA Level One Cable Belkin Cable
1 R
2 G
3 B
4 ID2 / RES USB D- (White) USB D+ (Green)
5 GND USB D+ (Green) USB D- (White)
6 RGND USB GND + GND USB GND + RGND
7 GGND USB GND + GND GND
8 BGND USB GND + GND GND
9 KEY / 5v USB 5v + 5v USB 5v + 5v
10 SGND USB GND + GND GND
11 ID0 / RES
12 ID1 / SDA
13 HSYNC
14 VSYNC
15 ID3 / SCL

From above, you can see that the voltage (thanks to VGA actually having a +5v pin as standard!) and GND are close-enough, but the USB data pins are backwards. You assholes.. here I was thinking there might be a standard. What to do here? Well, I simply hacked apart a USB extension cable and crossed over the D+ and D-. Note that there is absolutely no reason for using this cable in any other scenario!

DSC00034

After this, one last hurdle.. the Level One KVM has a male plug at either end, whereas the Belkin cables have female on the KVM side.

DSC00028 DSC00023 DSC00032

And the bloody thing just worked! Happy to not have to spend money on extra proprietary cables that I actually couldn't find anywhere.

3Apr/206

Sony HDR-AS100V Action Cam – Further Hacking

After a LOT of mucking around, trying to get a stream URL from the Action Cam, I did further googling on the defunct UStream service that the camera could, supposedly, stream live to. It wasn't long before I came across this mammoth thread on Github describing a few users' attempts to hack apart the APK that does the steaming and to fake a server with the intent to intercept the feed.

They use the Sony-PMCA-RE Project code to tweak settings on the camera and then built up an entire webserver to fake the Ustream service. None of this was beyond me, so I started by trying to work out if I could configure my camera to point at a server... (note that I've fudged any secrets in the console logs below...)

C:\Users\Steven\Downloads>pmca-console-v0.17-win.exe info -d libusb
Using drivers libusb-MSC, libusb-MTP
Looking for Sony devices

Querying mass storage device
Sony Camcorder is a camera in mass storage mode

Model:              HDR-AS100V
Product code:       0002426601
Serial number:      03035253
Firmware version:   2.00
GPS Data:           2020-04-02 00:00:00 - 2020-05-02 00:00:00
C:\Downloads>pmca-console-v0.17-win.exe stream -d libusb
Using drivers libusb-MSC, libusb-MTP
Looking for Sony devices

Querying mass storage device
Sony Camcorder is a camera in mass storage mode

twitterEnabled:     0
twitterConsumerKey: o9fJ2342342423433qg
twitterConsumerSecret: TTL4324234234234324324llM6EQdivTXesA
twitterAccessToken1:
twitterAccessTokenSecret:
twitterMessage:     Live Streaming from Action Cam by Sony
facebookEnabled:    0
facebookAccessToken:
facebookMessage:    Live Streaming from Action Cam by Sony
service:            0
enabled:            1
macId:
macSecret:
macIssueTime:       0000000000000000
unknown:            1
channels:           [0]
shortURL:
videoFormat:        1
supportedFormats:   [1, 3]
enableRecordMode:   1
videoTitle:         Recorded with Action Cam by Sony
videoDescription:   Shot 100% with Sony's Action Cam #SonyActionCam #ProveYourself
videoTag:
C:\Downloads>pmca-console-v0.17-win.exe updatershell -d libusb
Using drivers libusb-MSC, libusb-MTP
Looking for Sony devices

Querying mass storage device
Sony Camcorder is a camera in mass storage mode

Getting device info
Using firmware for model HDR-AS100V

Initializing firmware update
Traceback (most recent call last):
  File "C:\projects\sony-pmca-re\pmca-console.py", line 96, in <module>
  File "C:\projects\sony-pmca-re\pmca-console.py", line 82, in main
  File "C:\projects\sony-pmca-re\pmca\commands\usb.py", line 360, in updaterShellCommand
  File "C:\projects\sony-pmca-re\pmca\commands\usb.py", line 373, in firmwareUpdateCommandInternal
  File "C:\projects\sony-pmca-re\pmca\usb\sony.py", line 527, in checkGuard
  File "C:\projects\sony-pmca-re\pmca\usb\sony.py", line 501, in _sendWriteCommands
Exception: Firmware update error: Low battery
[9052] Failed to execute script pmca-console

Right... low battery... I charged it up and then tried again:

C:\Users\Steven\Downloads>pmca-console-v0.17-win.exe updatershell -d libusb
Using drivers libusb-MSC, libusb-MTP
Looking for Sony devices

Querying mass storage device
Sony Camcorder is a camera in mass storage mode

Getting device info
Using firmware for model HDR-AS100V

Initializing firmware update
Switching to updater mode

Waiting for camera to switch...
Please follow the instructions on the camera screen.

DSC04100

Cool, at this point the camera showed 'EXEC' on its LCD display. This kept flashing... and then the console app error'd out:

Operation timed out. Please run this command again when your camera has connected.

I pressed the record button on the back of the camera to try and force the 'EXEC' and it seemed to reboot. From here, it then wouldn't even come back to life. The battery charge light just stayed a fixed red, which I now think was an error indicator. After popping the battery out, I could get it back to the 'EXEC' screen via the console app, but it occurred to me that I actually had no idea what updater-shell even did. Instead I tried the stream fuction to push a UStream configuration file to the device as per the instructions here at Novex's project where he attempts to create his own UStream APK. Here's the config I used...

[
    [
        "twitterEnabled",
        0
    ],
    [
        "twitterConsumerKey",
        ""
    ],
    [
        "twitterConsumerSecret",
        ""
    ],
    [
        "twitterAccessToken1",
        ""
    ],
    [
        "twitterAccessTokenSecret",
        ""
    ],
    [
        "twitterMessage",
        "Live Streaming from Action Cam by Sony"
    ],
    [
        "facebookEnabled",
        0
    ],
    [
        "facebookAccessToken",
        ""
    ],
    [
        "facebookMessage",
        "Live Streaming from Action Cam by Sony"
    ],
    [
        "service",
        0
    ],
    [
        "enabled",
        1
    ],
    [
        "macId",
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    ],
    [
        "macSecret",
        "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    ],
    [
        "macIssueTime",
        "dbeaaaaa00000000"
    ],
    [
        "unknown",
        1
    ],
    [
        "channels",
        [
            12345678
        ]
    ],
    [
        "shortURL",
        "http://www.ustream.tv/channel/asdf"
    ],
    [
        "videoFormat",
        3
    ],
    [
        "supportedFormats",
        [
            1,
            3
        ]
    ],
    [
        "enableRecordMode",
        0
    ],
    [
        "videoTitle",
        "Recorded with Action Cam by Sony"
    ],
    [
        "videoDescription",
        "Shot 100% with Sony's Action Cam #SonyActionCam #ProveYourself"
    ],
    [
        "videoTag",
        ""
    ]
]

And then I smushed it into the camera using the console application...

C:\Downloads>pmca-console-v0.17-win.exe stream -w ustream.json -d libusb
Using drivers libusb-MSC, libusb-MTP
Looking for Sony devices

Querying mass storage device
Sony Camcorder is a camera in mass storage mode

Urrghh... what mode does it need to be in? Wait, is that even an error? Let's try use the buttons on the camera to switch it into Live mode...

DSC04105

Preparing?

DSC04103

No AP? Maybe it has no idea how to connect to a 5Ghz access point? Let's set it to my 2.4G secondary network, which nothing else uses, so I can isolate and watch any traffic. This took a little bit of hacking as the Sony Network Settings Utility needs the driver to be reverted back to USB Mass Storage. Jump in to Device Manager and force a driver 'update' back to the standard driver.

reset-to-usb-mass-storage

Now you can go into Network Settings and set your AP once more.

net-set-tool-1

wifi-connection incomplete-settings incomplete-settings-2

Note that it'll complain at the end that the settings are incomplete. Fortunately it still writes the AP configuration to the camera. After this, you'll have to switch back to the lib-usb driver and then re-upload the streaming settings.

remap-usb-driver-1 remap-usb-driver-2 remap-usb-driver-3

From here? Test! Unplug the camera and hit the Live mode again...

DSC04111

Auth Error? HDR-AS100V Official documentation indicates that this means it's failed to authenticate with UStream... makes sense to me! Can we hack my local network to make it auth to a fake server?

Network Setup for a Fake UStream Server

Since I want the raspi to be doing all the heavy lifting, I'm going to follow the instructions here at Luca Lanziani's project to set up a listener and a dns faker.

pi@raspberrypi:~ $ wget https://github.com/LucaLanziani/sony-camera-stream-receiver/archive/master.zip
--2020-04-03 16:01:51--  https://github.com/LucaLanziani/sony-camera-stream-receiver/archive/master.zip
Resolving github.com (github.com)... 13.237.44.5
Connecting to github.com (github.com)|13.237.44.5|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/LucaLanziani/sony-camera-stream-receiver/zip/master [following]
--2020-04-03 16:01:51--  https://codeload.github.com/LucaLanziani/sony-camera-stream-receiver/zip/master
Resolving codeload.github.com (codeload.github.com)... 52.63.100.255
Connecting to codeload.github.com (codeload.github.com)|52.63.100.255|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3790 (3.7K) [application/zip]
Saving to: ‘master.zip’

master.zip                                  100%[===========================>]   3.70K  --.-KB/s    in 0s      

2020-04-03 16:01:51 (7.39 MB/s) - ‘master.zip’ saved [3790/3790]

It downloaded easy enough... let's see what's inside!

pi@raspberrypi:~ $ mv master.zip sony-camera-receiver.zip
pi@raspberrypi:~ $ unzip sony-camera-receiver.zip 
Archive:  sony-camera-receiver.zip
dd4b1170f9cdeaabc2cb68eccff6b7f63214abce
   creating: sony-camera-stream-receiver-master/
 extracting: sony-camera-stream-receiver-master/.gitignore  
  inflating: sony-camera-stream-receiver-master/README.md  
  inflating: sony-camera-stream-receiver-master/dns_server.js  
  inflating: sony-camera-stream-receiver-master/index.js  
  inflating: sony-camera-stream-receiver-master/package.json  
  inflating: sony-camera-stream-receiver-master/rtmp_server.js  
  inflating: sony-camera-stream-receiver-master/web_server.js  
pi@raspberrypi:~ $ cd sony-camera-stream-receiver-master/
pi@raspberrypi:~/sony-camera-stream-receiver-master $ ls
dns_server.js  index.js  package.json  README.md  rtmp_server.js  web_server.js

Cool, everything we need. Following the instructions, we first need to download all the supporting node libraries.

pi@raspberrypi:~/sony-camera-stream-receiver-master $ npm i
npm WARN npm npm does not support Node.js v10.15.2
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 4, 6, 7, 8, 9.
npm WARN npm You can find the latest version at https://nodejs.org/
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN sony-cameras-stream-receiver@1.0.0 No repository field.

added 76 packages from 64 contributors in 17.452s

Cool, done. Now it's time to see if it'll actually run?

pi@raspberrypi:~/sony-camera-stream-receiver-master $ sudo node ./index.js --web.channel_number=12345678 --dns.external_ip=192.168.1.50
03/04/2020 16:09:24 16471 [INFO] Node Media Server v1.4.7
  dnsproxy:info we are up and listening at 192.168.1.50 on 53 +0ms
03/04/2020 16:09:24 16471 [INFO] Node Media Rtmp Server started on port: 1935
Server listening at http://0.0.0.0:80/
03/04/2020 16:09:26 16471 [INFO] There is a new version 2.1.6 that can be updated

Okey dokey.. it's up and running. The best thing we can do now is slap the new DNS server in our config and see what happens. After configuring my router and letting it reboot, nothing was resolving via .50. It seemed that .1 was still the DNS Server? I tried renewing my DHCP and flushing DNS, but nothing worked. Intead, I just hacked my local ethernet interface to point to .50 for DNS... woah! It works!

dhcp-1 dhcp-2 dhcp-3

But I can't hack the camera in the same way... so I need to work out why DHCP isn't giving me .50. I then realised I'd been reconfiguring my repeater and not my actual router!? I logged into .1 and set the DHCP configuration to have a Primary DNS of .50 and, well, shit just worked.

The camera still threw the Auth Error, so I totally disabled the DHCP on the repeater, because that really shouldn't be there, and rebooted the camera. Hitting the REC button on Live mode on the Action Cam then saw action on the raspi!

03/04/2020 16:58:47 16471 [INFO] [rtmp connect] id=SRMCPZ41 ip=::ffff:192.168.1.134 app=12345678 args={"app":"12345678","flashVer":"LNX 9,0,124,0","swfUrl":"http://www.ustream.tv/mobile.swf","tcUrl":"rtmp://api.ustream.tv/12345678","capabilities":1,"audioCodecs":1143,"videoCodecs":252,"videoFunction":1,"pageUrl":"http://www.ustream.tv","objectEncoding":0,"fpad":false}
03/04/2020 16:58:47 16471 [INFO] [rtmp publish] New stream. id=SRMCPZ41 streamPath=/12345678/broadcaster/live7665 streamId=1
03/04/2020 16:58:48 16471 [INFO] [rtmp publish] Handle video. id=SRMCPZ41 streamPath=/12345678/broadcaster/live7665 frame_type=1 codec_id=7 codec_name=H264 0x0
03/04/2020 16:58:48 16471 [INFO] [rtmp publish] Handle audio. id=SRMCPZ41 streamPath=/12345678/broadcaster/live7665 sound_format=10 sound_type=2 sound_size=1 sound_rate=3 codec_name=AAC 48000 2ch

03/04/2020 16:59:40 16471 [INFO] [rtmp connect] id=7YV3W0L2 ip=::ffff:192.168.1.121 app=12345678/broadcaster args={"app":"12345678/broadcaster","flashVer":"LNX 9,0,124,2","tcUrl":"rtmp://192.168.1.50:1935/12345678/broadcaster","fpad":false,"capabilities":15,"audioCodecs":4071,"videoCodecs":252,"videoFunction":1}
03/04/2020 16:59:40 16471 [INFO] [rtmp play] Join stream. id=7YV3W0L2 streamPath=/12345678/broadcaster/live7665  streamId=1

And then pointing VLC at rtmp://192.168.1.50/12345678/broadcaster/live7665 got me....

traiiiinnnnssss

Traaaaaiinnnsssss... Now to find the perfect angle. Note that you get an 'ONAIR' message on the LCD when it's ... on air.

DSC00001

Sure, not the best mounting... I'll work on that. I've also got a waterproof case for it that I'll need to hack a hole into to get the USB power through.

Productionising

Having the raspi be the DNS server is a little scary. But I suppose this is where secondary DNS servers come in? If we put 8.8.8.8 for the secondary, does it get used when the primary is down? Turns out it doesn't work that way, so I'll need to keep the raspi up and running 100% of the time!

C:\Users\Steven>ipconfig /all
Ethernet adapter Ethernet:
   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Intel(R) Ethernet Connection (2) I219-V
   Physical Address. . . . . . . . . : 30-5A-3A-81-E1-1B
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes
   IPv4 Address. . . . . . . . . . . : 192.168.1.121(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.1.1
   DHCP Server . . . . . . . . . . . : 192.168.1.1
   DNS Servers . . . . . . . . . . . : 192.168.1.50
                                       8.8.8.8
   NetBIOS over Tcpip. . . . . . . . : Enabled
C:\Users\Steven>ipconfig /flushdns
Windows IP Configuration
Successfully flushed the DNS Resolver Cache.
C:\Users\Steven>nslookup google.com
DNS request timed out.
    timeout was 2 seconds.
Server:  UnKnown
Address:  192.168.1.50

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** Request to UnKnown timed-out

For some reason I really enjoy the spelling of 'UnKnown'. Regardless, the secondary has not kicked in! With this news, I suppose it'd be best to learn how to keep that service up and running 24/7 on the pi. Instead, I have decided to not even go ahead with this camera! It's wide-view fish-eye angle just isn't wide enough to get the trains close enough and the cityscape in the shot... I therefore don't see any advantage over my current camera.

So! A learning experience! For those who want to use a Sony Action Cam HDR-AS100V as a livestreaming camera, it's plausible!

3Apr/201

Streaming from a Sony HDR-AS100V Action Cam

This is a cool camera. I picked it up from the Hard Off in Kagoshima whilst I was visiting the southernmost JR Railway station in Japan. I then used it to take a miriad of videos, especially from the balcony at the apartment in Shin Osaka.

DSC04151

DSC04152 DSC04153 DSC04156

Whilst it works great recording by itself, you can also use the Play Mobile (now Imaging Edge Mobile) application from Sony to control it remotely. The application uses the phones Wifi to connect to the camera, which acts as a wifi access point. From there, it shows a live view of what the camera can see whilst you're trying to line up the next shot. You can even control the camera remotely with the buttons on screen, being able to start and stop recording very easily... especially without bumping the camera!

Screenshot 20200331-143248

I was hoping Sony would release the same software for the PC and allow me to connect wirelessly to the camera. This would then let me sniff the traffic and get the video stream live link, but alas, it's only available for mobile devices. Wait!, you say, there is a version of Play Memories for windows! Sure, go ahead and download it... install it even! It'll connect to your camera, but there's no ability to see the live stream from the lens... I tried... trust me....

camera-options actioncam-import streaming-tool

With the USB camera connected, you'll get the screens above. They let you update firmware and manage settings, but not much else. Of course, there's also the file transfer functionality to let you download the images and videos you've taken. Interestingly, the last image shows the second pane of the Network Settings tab which allows you to configure the camera to upload to UStream automatically. Turns out that this was a 'thing' back in the day and not really practical anymore: IBM bought UStream and the service is no longer free... nor could I get it to work, even with a trial account.

Can we create a network to inspect the Wifi?

So, I had a plan. I have a Vonets VAR11N-300 that allows an ethernet cabled device to access an access point over Wifi. With this, I could use an ethernet port on my laptop to connect to the camera. The Wifi adapter in the laptop could then create an ad-hoc network that my phone could connect to. If I bridged the ethernet to the Wifi, connected my phone ad-hoc to the wifi network created by the laptop, then I could possibly pass the traffic through the laptop and use wireshark to listen in?

s-l1600

As I was plugging this all together, traffic started flowing without client application requesting anything! I'd not yet bridged the adapters, but I'd installed Wireshark and had the VAR11N-300 connected to the camera and, all of a sudden, I'd noticed jitters on the traffic graph for the ethernet interface on the front page of Wireshark. The ethernet port seems to have received an IP from the camera since it was acting as a terminating host and not an ethernet bridge! For everyones information: the IP range is 196.168.0.x, with IPs dished out from 1 and the camera being 192.168.122.1. With the little graph jumping around, I decided to listen in and have a look!

ws-1 ws-2 upnp-xml

Ok so, from left to right above... the Wireshark main screen with my miriad of interfaces. You may notice that I have Wifi-2 selected there and there's traffic flowing on it... At this point, realising that I didn't need the mobile application to trigger data flow from the camera, I'd slapped a USB Wifi dongle into my main desktop so that I could work in comfort. The second screen is the main window of Wireshark once you're sniffing. You'll see a huge list of traffic up the top. Wireshark, without filters, will just present everything it can possibly see. Each row is a packet sent over the Wifi and you may need to combine multiple rows to see an entire picture, depending on what you're looking for. Usually, if this was my main network interface, I'd use a filter at the top with either ip.dest == 192.x.x.x or ip.src == 192.x.x.x to limit the displayed data, but fortunately this interface was only talking to the camera.

The second shot there has a very interesting packet displayed. It turns out that the camera is broadcasting UPnP information, telling anyone listening on the immediate network how to find it! No wonder, once you've connected your phone to the camera, that it can find it. It doesn't even have to look as the camera just yells it out every few seconds. Let's check out the data we're receiving...

<?xml version="1.0" encoding="utf-8"?>
<root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:dlna="urn:schemas-dlna-org:device-1-0" xmlns:av="urn:schemas-sony-com:av">
	<specVersion>
		<major>1</major>
		<minor>0</minor>
	</specVersion>
	<device>
		<dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMS-1.50</dlna:X_DLNADOC>
		<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>
		<friendlyName>HDR-AS100V</friendlyName>
		<manufacturer>Sony Corporation</manufacturer>
		<manufacturerURL>http://www.sony.com/</manufacturerURL>
		<modelDescription>SonyDigitalMediaServer</modelDescription>
		<modelName>SonyImagingDevice</modelName>
		<modelURL>http://www.sony.net/</modelURL>
		<UDN>uuid:00000000-0005-0010-8000-fcc2de658d5e</UDN>
		<serviceList>
			<service>
				<serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType>
				<serviceId>urn:upnp-org:serviceId:ContentDirectory</serviceId>
				<SCPDURL>/CdsDesc.xml</SCPDURL>
				<controlURL>/upnp/control/ContentDirectory</controlURL>
				<eventSubURL>/upnp/event/ContentDirectory</eventSubURL>
			</service>
			<service>
				<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
				<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
				<SCPDURL>/CmsDesc.xml</SCPDURL>
				<controlURL>/upnp/control/ConnectionManager</controlURL>
				<eventSubURL>/upnp/event/ConnectionManager</eventSubURL>
			</service>
			<service>
				<serviceType>urn:schemas-sony-com:service:ScalarWebAPI:1</serviceType>
				<serviceId>urn:schemas-sony-com:serviceId:ScalarWebAPI</serviceId>
				<SCPDURL>/ScalarWebApiDesc.xml</SCPDURL>
				<controlURL/>
				<eventSubURL/>
			</service>
		</serviceList>
		<iconList>
			<icon>
				<mimetype>image/jpeg</mimetype>
				<width>48</width>
				<height>48</height>
				<depth>24</depth>
				<url>/DLNA_camera_48.jpg</url>
			</icon>
			<icon>
				<mimetype>image/jpeg</mimetype>
				<width>120</width>
				<height>120</height>
				<depth>24</depth>
				<url>/DLNA_camera_120.jpg</url>
			</icon>
			<icon>
				<mimetype>image/png</mimetype>
				<width>48</width>
				<height>48</height>
				<depth>24</depth>
				<url>/DLNA_camera_48.png</url>
			</icon>
			<icon>
				<mimetype>image/png</mimetype>
				<width>120</width>
				<height>120</height>
				<depth>24</depth>
				<url>/DLNA_camera_120.png</url>
			</icon>
		</iconList>
		<av:X_ScalarWebAPI_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
			<av:X_ScalarWebAPI_Version>1.0</av:X_ScalarWebAPI_Version>
			<av:X_ScalarWebAPI_ServiceList>
				<av:X_ScalarWebAPI_Service>
					<av:X_ScalarWebAPI_ServiceType>guide</av:X_ScalarWebAPI_ServiceType>
					<av:X_ScalarWebAPI_ActionList_URL>http://192.168.122.1:10000/sony</av:X_ScalarWebAPI_ActionList_URL>
					<av:X_ScalarWebAPI_AccessType />
				</av:X_ScalarWebAPI_Service>
				<av:X_ScalarWebAPI_Service>
					<av:X_ScalarWebAPI_ServiceType>accessControl</av:X_ScalarWebAPI_ServiceType>
					<av:X_ScalarWebAPI_ActionList_URL>http://192.168.122.1:10000/sony</av:X_ScalarWebAPI_ActionList_URL>
					<av:X_ScalarWebAPI_AccessType />
				</av:X_ScalarWebAPI_Service>
				<av:X_ScalarWebAPI_Service>
					<av:X_ScalarWebAPI_ServiceType>camera</av:X_ScalarWebAPI_ServiceType>
					<av:X_ScalarWebAPI_ActionList_URL>http://192.168.122.1:10000/sony</av:X_ScalarWebAPI_ActionList_URL>
					<av:X_ScalarWebAPI_AccessType />
				</av:X_ScalarWebAPI_Service>
			</av:X_ScalarWebAPI_ServiceList>
			<av:X_ScalarWebAPI_ImagingDevice>
				<av:X_ScalarWebAPI_LiveView_URL>http://192.168.122.1:60152/liveview.JPG?%211234%21http%2dget%3a%2a%3aimage%2fjpeg%3a%2a%21%21%21%21%21</av:X_ScalarWebAPI_LiveView_URL>
				<av:X_ScalarWebAPI_DefaultFunction>RemoteShooting</av:X_ScalarWebAPI_DefaultFunction>
			</av:X_ScalarWebAPI_ImagingDevice>
		</av:X_ScalarWebAPI_DeviceInfo>
	</device>
</root>

Oooowwweee... Check that link at the bottom!? X_ScalarWebAPI_LiveView_URL? Really? Can it be this easy? I slapped it into a browser and no... it's not this easy... the browser just doesn't respond as it's constantly being fed a stream of data and doesn't know what to do with it! Turns out this stream is a motion-jpeg or some frame-by-frame binary flow that isn't a standard video stream. So, what to do? Google the hell out of those keywords and see who has already come to our rescue!

First hit was a post on stackoverflow asking 'How to get Sony ScalarWebAPI method list'. From the responses, one person suggested to send the camera JSON via a post so that you can see what functions you can call. One such function is getMethodTypes and can be called via the following post body:

{"method": "getMethodTypes", "params": [""], "id": 1, "version": "1.0"}

posty

Using Postman, I got the following result...

{
    "id": 1,
    "results": [
        [
            "actTakePicture",
            [],
            [
                "string*"
            ],
            "1.0"
        ],
        [
            "getApplicationInfo",
            [],
            [
                "string",
                "string"
            ],
            "1.0"
        ],
        [
            "getAvailableApiList",
            [],
            [
                "string*"
            ],
            "1.0"
        ],
        [
            "getAvailableCameraFunction",
            [],
            [
                "string",
                "string*"
            ],
            "1.0"
        ],
        [
            "getAvailableMovieQuality",
            [],
            [
                "string",
                "string*"
            ],
            "1.0"
        ],
        [
            "getAvailableShootMode",
            [],
            [
                "string",
                "string*"
            ],
            "1.0"
        ],
        [
            "getAvailableSteadyMode",
            [],
            [
                "string",
                "string*"
            ],
            "1.0"
        ],
        [
            "getCameraFunction",
            [],
            [
                "string"
            ],
            "1.0"
        ],
        [
            "getEvent",
            [
                "bool"
            ],
            [
                "{\"type\":\"string\", \"names\":\"string*\"}",
                "{\"type\":\"string\", \"cameraStatus\":\"string\"}",
                "{\"type\":\"string\", \"zoomPosition\":\"int\", \"zoomNumberBox\":\"int\", \"zoomIndexCurrentBox\":\"int\", \"zoomPositionCurrentBox\":\"int\"}",
                "{\"type\":\"string\", \"liveviewStatus\":\"bool\"}",
                "{\"type\":\"string\", \"liveviewOrientation\":\"string\"}",
                "{\"type\":\"string\", \"takePictureUrl\":\"string*\"}*",
                "{\"type\":\"string\", \"continuousError\":\"string\", \"isContinued\":\"bool\"}*",
                "{\"type\":\"string\", \"triggeredError\":\"string*\"}",
                "{\"type\":\"string\", \"sceneRecognition\":\"string\", \"steadyRecognition\":\"string\", \"motionRecognition\":\"string\"}",
                "{\"type\":\"string\", \"formatResult\":\"string\"}",
                "{\"type\":\"string\", \"storageID\":\"string\", \"recordTarget\":\"bool\", \"numberOfRecordableImages\":\"int\", \"recordableTime\":\"int\", \"storageDescription\":\"string\"}*",
                "{\"type\":\"string\", \"currentBeepMode\":\"string\", \"beepModeCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentCameraFunction\":\"string\", \"cameraFunctionCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentMovieQuality\":\"string\", \"movieQualityCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"checkAvailability\":\"bool\", \"currentAspect\":\"string\", \"currentSize\":\"string\"}",
                "{\"type\":\"string\", \"cameraFunctionResult\":\"string\"}",
                "{\"type\":\"string\", \"currentSteadyMode\":\"string\", \"steadyModeCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentViewAngle\":\"int\", \"viewAngleCandidates\":\"int*\"}",
                "{\"type\":\"string\", \"currentExposureMode\":\"string\", \"exposureModeCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentPostviewImageSize\":\"string\", \"postviewImageSizeCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentSelfTimer\":\"int\", \"selfTimerCandidates\":\"int*\"}",
                "{\"type\":\"string\", \"currentShootMode\":\"string\", \"shootModeCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentAELock\":\"bool\", \"aeLockCandidates\":\"bool*\"}",
                "{\"type\":\"string\", \"checkAvailability\":\"bool\", \"currentBracketShootMode\":\"string\", \"currentBracketShootModeOption\":\"string\"}",
                "{\"type\":\"string\", \"checkAvailability\":\"bool\", \"currentCreativeStyle\":\"string\", \"currentCreativeStyleContrast\":\"int\", \"currentCreativeStyleSaturation\":\"int\", \"currentCreativeStyleSharpness\":\"int\"}",
                "{\"type\":\"string\", \"currentExposureCompensation\":\"int\", \"maxExposureCompensation\":\"int\", \"minExposureCompensation\":\"int\", \"stepIndexOfExposureCompensation\":\"int\"}",
                "{\"type\":\"string\", \"currentFlashMode\":\"string\", \"flashModeCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentFNumber\":\"string\", \"fNumberCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentFocusMode\":\"string\", \"focusModeCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"currentIsoSpeedRate\":\"string\", \"isoSpeedRateCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"checkAvailability\":\"bool\", \"currentPictureEffect\":\"string\", \"currentPictureEffectOption\":\"string\"}",
                "{\"type\":\"string\", \"isShifted\":\"bool\"}",
                "{\"type\":\"string\", \"currentShutterSpeed\":\"string\", \"shutterSpeedCandidates\":\"string*\"}",
                "{\"type\":\"string\", \"checkAvailability\":\"bool\", \"currentWhiteBalanceMode\":\"string\", \"currentColorTemperature\":\"int\"}",
                "{\"type\":\"string\", \"currentSet\":\"bool\", \"currentTouchCoordinates\":\"double*\"}"
            ],
            "1.0"
        ],
        [
            "getMethodTypes",
            [
                "string"
            ],
            [
                "string",
                "string*",
                "string*",
                "string"
            ],
            "1.0"
        ],
        [
            "getMovieQuality",
            [],
            [
                "string"
            ],
            "1.0"
        ],
        [
            "getShootMode",
            [],
            [
                "string"
            ],
            "1.0"
        ],
        [
            "getSteadyMode",
            [],
            [
                "string"
            ],
            "1.0"
        ],
        [
            "getStorageInformation",
            [],
            [
                "{\"storageID\":\"string\", \"recordTarget\":\"bool\", \"numberOfRecordableImages\":\"int\", \"recordableTime\":\"int\", \"storageDescription\":\"string\"}*"
            ],
            "1.0"
        ],
        [
            "getSupportedCameraFunction",
            [],
            [
                "string*"
            ],
            "1.0"
        ],
        [
            "getSupportedMovieQuality",
            [],
            [
                "string*"
            ],
            "1.0"
        ],
        [
            "getSupportedShootMode",
            [],
            [
                "string*"
            ],
            "1.0"
        ],
        [
            "getSupportedSteadyMode",
            [],
            [
                "string*"
            ],
            "1.0"
        ],
        [
            "getVersions",
            [],
            [
                "string*"
            ],
            "1.0"
        ],
        [
            "setCameraFunction",
            [
                "string"
            ],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "setMovieQuality",
            [
                "string"
            ],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "setShootMode",
            [
                "string"
            ],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "setSteadyMode",
            [
                "string"
            ],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "startIntervalStillRec",
            [],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "startLiveview",
            [],
            [
                "string"
            ],
            "1.0"
        ],
        [
            "startMovieRec",
            [],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "stopIntervalStillRec",
            [],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "stopLiveview",
            [],
            [
                "int"
            ],
            "1.0"
        ],
        [
            "stopMovieRec",
            [],
            [
                "string"
            ],
            "1.0"
        ]
    ]
}

So, there's a startLiveview command down the bottom there... maybe I need to call this prior to trying to actually display the URL in a browser? It easily be called via Postman with the body:

{"method": "startLiveview","params" : [],"id" : 1,"version" : "1.0"}

You'll get the following result...

{
    "id": 1,
    "result": [
        "http://192.168.122.1:60152/liveview.JPG?%211234%21http%2dget%3a%2a%3aimage%2fjpeg%3a%2a%21%21%21%21%21"
    ]
}

We knew this link already from the XML above, but does the video now work? I slapped the URL into the browser but didn't have much luck. So... a little more digging and I found the following: Tony Jan's work on decode the Sony stream written in Ruby, kazyx's kz-remote-api written in C# and twenzel's version called SonyCameraRemoteControl also in C#.Finally, with the term 'liveview' added to my search, I hit cryptofuture's liveView project which contained binaries to run really easy on Windows.

livecam-py camera-shot-1 camera-shot-3

Horrible image quality... but we have it! A livestream from the HDR-AS100V! I wrapped it up at that point, since you can see it was past midnight.

Getting this out to the world!

Nice, we have a connection. Next step? Pipe this to Youtube. I was going to use a Raspberry Pi, so Ruby will an easy choice and therefore Tony's library was tested. Gem is installed by default...

pi@raspberrypi:~ $ sudo gem install sonycam
Fetching: thor-1.0.1.gem (100%)
Successfully installed thor-1.0.1
Fetching: sonycam-1.3.2.gem (100%)
Successfully installed sonycam-1.3.2
Parsing documentation for thor-1.0.1
Installing ri documentation for thor-1.0.1
Parsing documentation for sonycam-1.3.2
Installing ri documentation for sonycam-1.3.2
Done installing documentation for thor, sonycam after 3 seconds
2 gems installed

Just for fun, after hooking up the wireless... try to take a picture?

pi@raspberrypi:~ $ sonycam api actTakePicture
Can not find /home/pi/.sonycam, start scanning...
Found location: http://192.168.122.1:64321/DmsRmtDesc.xml
Device description file saved to /home/pi/.sonycam
Traceback (most recent call last):
        8: from /usr/local/bin/sonycam:23:in `<main>'
        7: from /usr/local/bin/sonycam:23:in `load'
        6: from /var/lib/gems/2.5.0/gems/sonycam-1.3.2/bin/sonycam:3:in `<top (required)>'
        5: from /var/lib/gems/2.5.0/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
        4: from /var/lib/gems/2.5.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
        3: from /var/lib/gems/2.5.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
        2: from /var/lib/gems/2.5.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
        1: from /var/lib/gems/2.5.0/gems/sonycam-1.3.2/lib/sonycam/cli.rb:49:in `api'
/var/lib/gems/2.5.0/gems/sonycam-1.3.2/lib/sonycam/api.rb:17:in `request': Sonycam::Error::IllegalRequest

I suppose, this is an Action Cam and not an SLR? Let's try the livestream to MP4.

sonycam liveview | ffmpeg -f image2pipe -c mjpeg -i pipe:0 -codec copy liveview.mp4

Trying to open the video file whilst the recording was happening didn't work... but it opened successfully once it was stopped.

The final option was to use ffserver, but it turns out that it's ancient technology that's been deprecated in FFmpeg. I quickly looked at the age of the repository and noticed it was last updated 6 years ago!

In the end, it turns out that the liveview is only ever outputted at 635x300-something. It's not HD! Nooooo... alllll... thissss... timmmeeee... speennntt.... It seems that there's another call for startLiveviewWithSize, but my camera doesn't support this. Oh right, only the full-frame cameras do!? And look at that link, they've called Liveview "viewfinder"! Of course it wont be full resolution.

HDMI Output

What goes out, must come in? Sure, this thing has a mini/micro/something HDMI port in its ass... but how does that help me? YouTube doesn't have a HDMI input plug! Well, eBay does have crappy HDMI to USB converters.. so..

s-l500

I bought that thing... and got this input via VLC. The actual software they wanted to use needed Direct X Movie/Video WMV software installed and Windows 10 didn't want to even care.

HDMIin

Image quality was OK, but no colour? I didn't bother digging further as I really didn't want HDMI cables running all over the shop.

Let's just use the old camera

Oh well.. it's back to the old camera until I find another method of getting this camera to stream. Here it is, right now, streaming live to the world from my balcony.

DSC00002

Hahahaa... do you like my handywork? (Go over here to Youtube if the embed below is broken.)

I'll update if I manage to find a better method. There's hints of people hacking apart the APK (yes, these cameras run Android!) on the unit that streams to UStream.
Why can't we just create one that provides an RTSP endpoint, like my camera above?